Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. Clever Code
  4. A (not so subtle) leak...

A (not so subtle) leak...

Scheduled Pinned Locked Moved Clever Code
csharpquestion
14 Posts 9 Posters 9 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Chris Meech

    Since there's no horizontal scroll, your code leaks right off the edge of the screen. :cool:

    Chris Meech I am Canadian. [heard in a local bar] Donate to help Conquer Cancer[^]

    J Offline
    J Offline
    Jan van den Baard
    wrote on last edited by
    #4

    Sorry about that... Did not notice it (damn those 1920x1200 screens :-\ )

    We are the all singing, all dancing crap of the world. - Tyler Durden

    P 1 Reply Last reply
    0
    • A AWdrius

      Is it because of the ref byte[] buffer?

      J Offline
      J Offline
      Jan van den Baard
      wrote on last edited by
      #5

      No. When the timeout occures the Receive() method does exit and returns -1 but the thread occupied by the BeginReceive() call does not exit. In other words it slowly (or fast depending on how often it used) fill's up all threads on the ThreadPool with nasty consequences for everything else depending on the ThreadPool. Changing

      else
      {
      return -1;
      }

      to

      else
      {
      state.Socket.Close();
      return -1;
      }

      fixed it.

      We are the all singing, all dancing crap of the world. - Tyler Durden

      1 Reply Last reply
      0
      • J Jan van den Baard

        Sorry about that... Did not notice it (damn those 1920x1200 screens :-\ )

        We are the all singing, all dancing crap of the world. - Tyler Durden

        P Offline
        P Offline
        PIEBALDconsult
        wrote on last edited by
        #6

        It's not the screen's fault.

        1 Reply Last reply
        0
        • J Jan van den Baard

          In a project I am working on I had to do NTP time synchronisation on a WindowsCE client. The UdpClient it's Receive() call does not time out so I found this solution on the web:

          public class UdpTimeoutClient : UdpClient
          {
          	private class SocketState
          	{
          		public Socket Socket;
          		public byte\[\] Buffer;
          		public int BytesRead;
          		public ManualResetEvent WaitHandle;
          
          		public SocketState()
          		{
          			Socket = null;
          			Buffer = null;
          			BytesRead = 0;
          			WaitHandle = new ManualResetEvent(false);
          		}
          	}
          
          	private static void ReceiveCallback(IAsyncResult ar)
          	{
          		SocketState state = (SocketState)ar.AsyncState;
          		try
          		{
          			state.BytesRead = state.Socket.EndReceive(ar);
          		}
          		catch
          		{
          		}
          		state.WaitHandle.Set();
          	}
          
          	public int Receive(ref byte\[\] buffer, int timeout)
          	{
          		SocketState state;
          		AsyncCallback callback;
          		IAsyncResult result;
          		
          		state = new SocketState();
          		state.Socket = Client;
          		state.Buffer = buffer;
          
          		callback = new System.AsyncCallback(UdpTimeoutClient.ReceiveCallback);
          		result = state.Socket.BeginReceive(state.Buffer, 0, state.Buffer.Length, System.Net.Sockets.SocketFlags.None, callback, state);
          		if (state.WaitHandle.WaitOne(timeout, false))
          		{
          			return state.BytesRead;
          		}
          		else
          		{
          			return -1;
          		}
          	}
          }
          

          Can you spot the leak?

          We are the all singing, all dancing crap of the world. - Tyler Durden

          L Offline
          L Offline
          leppie
          wrote on last edited by
          #7

          Jan van den Baard wrote:

          Can you spot the leak?

          Why use an asynchronous approach when you handle it synchronously?

          xacc.ide - now with IronScheme support
          IronScheme - 1.0 alpha 1 out now

          J 1 Reply Last reply
          0
          • L leppie

            Jan van den Baard wrote:

            Can you spot the leak?

            Why use an asynchronous approach when you handle it synchronously?

            xacc.ide - now with IronScheme support
            IronScheme - 1.0 alpha 1 out now

            J Offline
            J Offline
            Jan van den Baard
            wrote on last edited by
            #8

            To be able to timeout from receiving the data. The method should be handled synchronously but it should also be able to timeout. When I would use the synchronous Receive() call on the UdpClient it would wait indefinitly for data to arive. I.E. the call would never exit. This way I can atleast timeout when receiving expected data takes to long. Our NTP client does a request on the NTP server at regular intervals. The NTP server may not be available all the time. If I where to use the Receive() approach the NTP syncing would "hang" after the first failed synchronisation attempt.

            We are the all singing, all dancing crap of the world. - Tyler Durden

            1 Reply Last reply
            0
            • J Jan van den Baard

              In a project I am working on I had to do NTP time synchronisation on a WindowsCE client. The UdpClient it's Receive() call does not time out so I found this solution on the web:

              public class UdpTimeoutClient : UdpClient
              {
              	private class SocketState
              	{
              		public Socket Socket;
              		public byte\[\] Buffer;
              		public int BytesRead;
              		public ManualResetEvent WaitHandle;
              
              		public SocketState()
              		{
              			Socket = null;
              			Buffer = null;
              			BytesRead = 0;
              			WaitHandle = new ManualResetEvent(false);
              		}
              	}
              
              	private static void ReceiveCallback(IAsyncResult ar)
              	{
              		SocketState state = (SocketState)ar.AsyncState;
              		try
              		{
              			state.BytesRead = state.Socket.EndReceive(ar);
              		}
              		catch
              		{
              		}
              		state.WaitHandle.Set();
              	}
              
              	public int Receive(ref byte\[\] buffer, int timeout)
              	{
              		SocketState state;
              		AsyncCallback callback;
              		IAsyncResult result;
              		
              		state = new SocketState();
              		state.Socket = Client;
              		state.Buffer = buffer;
              
              		callback = new System.AsyncCallback(UdpTimeoutClient.ReceiveCallback);
              		result = state.Socket.BeginReceive(state.Buffer, 0, state.Buffer.Length, System.Net.Sockets.SocketFlags.None, callback, state);
              		if (state.WaitHandle.WaitOne(timeout, false))
              		{
              			return state.BytesRead;
              		}
              		else
              		{
              			return -1;
              		}
              	}
              }
              

              Can you spot the leak?

              We are the all singing, all dancing crap of the world. - Tyler Durden

              M Offline
              M Offline
              Mike Dimmick
              wrote on last edited by
              #9

              (Note: in addition to the problem you found.) You don't have a Dispose method, implement IDisposable, and you don't dispose of Socket nor WaitHandle. It will eventually fall through to the objects' finalizers, but that will happen at an unpredictable time in the future. Meanwhile your object, and any objects it's referencing, is hanging around on the heap. GC deals with objects that require finalization by putting them on a list of objects to be finalized - the freachable queue (for 'finalizable objects still reachable'.) Then, another thread processes this queue. The memory can only be freed once the GC runs a second time. Unfortunately it also tunes to run less frequently if more objects survive a GC. Also, if you're deriving from UdpClient, you already have a socket. Unfortunately you can't access it from a derived class. Unless you really need to be able to dynamically substitute a UdpTimeoutClient for a UdpClient, I'd remove the inheritance link and make it a standalone class. Actually, I can see no reason that UdpClient was left unsealed.

              DoEvents: Generating unexpected recursion since 1991

              J 1 Reply Last reply
              0
              • M Mike Dimmick

                (Note: in addition to the problem you found.) You don't have a Dispose method, implement IDisposable, and you don't dispose of Socket nor WaitHandle. It will eventually fall through to the objects' finalizers, but that will happen at an unpredictable time in the future. Meanwhile your object, and any objects it's referencing, is hanging around on the heap. GC deals with objects that require finalization by putting them on a list of objects to be finalized - the freachable queue (for 'finalizable objects still reachable'.) Then, another thread processes this queue. The memory can only be freed once the GC runs a second time. Unfortunately it also tunes to run less frequently if more objects survive a GC. Also, if you're deriving from UdpClient, you already have a socket. Unfortunately you can't access it from a derived class. Unless you really need to be able to dynamically substitute a UdpTimeoutClient for a UdpClient, I'd remove the inheritance link and make it a standalone class. Actually, I can see no reason that UdpClient was left unsealed.

                DoEvents: Generating unexpected recursion since 1991

                J Offline
                J Offline
                Jan van den Baard
                wrote on last edited by
                #10

                Mike Dimmick wrote:

                You don't have a Dispose method, implement IDisposable, and you don't dispose of Socket nor WaitHandle.

                Unless I am mistaking the Dispose() of UdpClient does the necessary cleanup for me.

                Mike Dimmick wrote:

                Also, if you're deriving from UdpClient, you already have a socket. Unfortunately you can't access it from a derived class.

                Well you can. Through the Client property. The class uses the socket supplied by this property. Disposing of the UdpTimeoutClient object should perform all necessary cleanup. Not sure about the WaitHandle though...

                1 Reply Last reply
                0
                • J Jan van den Baard

                  In a project I am working on I had to do NTP time synchronisation on a WindowsCE client. The UdpClient it's Receive() call does not time out so I found this solution on the web:

                  public class UdpTimeoutClient : UdpClient
                  {
                  	private class SocketState
                  	{
                  		public Socket Socket;
                  		public byte\[\] Buffer;
                  		public int BytesRead;
                  		public ManualResetEvent WaitHandle;
                  
                  		public SocketState()
                  		{
                  			Socket = null;
                  			Buffer = null;
                  			BytesRead = 0;
                  			WaitHandle = new ManualResetEvent(false);
                  		}
                  	}
                  
                  	private static void ReceiveCallback(IAsyncResult ar)
                  	{
                  		SocketState state = (SocketState)ar.AsyncState;
                  		try
                  		{
                  			state.BytesRead = state.Socket.EndReceive(ar);
                  		}
                  		catch
                  		{
                  		}
                  		state.WaitHandle.Set();
                  	}
                  
                  	public int Receive(ref byte\[\] buffer, int timeout)
                  	{
                  		SocketState state;
                  		AsyncCallback callback;
                  		IAsyncResult result;
                  		
                  		state = new SocketState();
                  		state.Socket = Client;
                  		state.Buffer = buffer;
                  
                  		callback = new System.AsyncCallback(UdpTimeoutClient.ReceiveCallback);
                  		result = state.Socket.BeginReceive(state.Buffer, 0, state.Buffer.Length, System.Net.Sockets.SocketFlags.None, callback, state);
                  		if (state.WaitHandle.WaitOne(timeout, false))
                  		{
                  			return state.BytesRead;
                  		}
                  		else
                  		{
                  			return -1;
                  		}
                  	}
                  }
                  

                  Can you spot the leak?

                  We are the all singing, all dancing crap of the world. - Tyler Durden

                  M Offline
                  M Offline
                  MrPlankton
                  wrote on last edited by
                  #11

                  result = state.Socket.BeginReceive(state.Buffer, 0, state.Buffer.Length, System.Net.Sockets.SocketFlags.None, callback, state); looks potentially recursive, behaviour problem in parent class UdpClient?

                  MrPlankton

                  1 Reply Last reply
                  0
                  • J Jan van den Baard

                    In a project I am working on I had to do NTP time synchronisation on a WindowsCE client. The UdpClient it's Receive() call does not time out so I found this solution on the web:

                    public class UdpTimeoutClient : UdpClient
                    {
                    	private class SocketState
                    	{
                    		public Socket Socket;
                    		public byte\[\] Buffer;
                    		public int BytesRead;
                    		public ManualResetEvent WaitHandle;
                    
                    		public SocketState()
                    		{
                    			Socket = null;
                    			Buffer = null;
                    			BytesRead = 0;
                    			WaitHandle = new ManualResetEvent(false);
                    		}
                    	}
                    
                    	private static void ReceiveCallback(IAsyncResult ar)
                    	{
                    		SocketState state = (SocketState)ar.AsyncState;
                    		try
                    		{
                    			state.BytesRead = state.Socket.EndReceive(ar);
                    		}
                    		catch
                    		{
                    		}
                    		state.WaitHandle.Set();
                    	}
                    
                    	public int Receive(ref byte\[\] buffer, int timeout)
                    	{
                    		SocketState state;
                    		AsyncCallback callback;
                    		IAsyncResult result;
                    		
                    		state = new SocketState();
                    		state.Socket = Client;
                    		state.Buffer = buffer;
                    
                    		callback = new System.AsyncCallback(UdpTimeoutClient.ReceiveCallback);
                    		result = state.Socket.BeginReceive(state.Buffer, 0, state.Buffer.Length, System.Net.Sockets.SocketFlags.None, callback, state);
                    		if (state.WaitHandle.WaitOne(timeout, false))
                    		{
                    			return state.BytesRead;
                    		}
                    		else
                    		{
                    			return -1;
                    		}
                    	}
                    }
                    

                    Can you spot the leak?

                    We are the all singing, all dancing crap of the world. - Tyler Durden

                    C Offline
                    C Offline
                    chandrareddy
                    wrote on last edited by
                    #12

                    any updates regarding above issue? :)

                    J E 2 Replies Last reply
                    0
                    • C chandrareddy

                      any updates regarding above issue? :)

                      J Offline
                      J Offline
                      Jan van den Baard
                      wrote on last edited by
                      #13

                      Yes. See my response to the message from AWdrius above.

                      We are the all singing, all dancing crap of the world. - Tyler Durden

                      1 Reply Last reply
                      0
                      • C chandrareddy

                        any updates regarding above issue? :)

                        E Offline
                        E Offline
                        Expert Coming
                        wrote on last edited by
                        #14

                        The OP said what was wrong up above.

                        The best way to accelerate a Macintosh is at 9.8m/sec² - Marcus Dolengo

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups