Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

the correct technique for releasing a socket/event/ummaged code with the dispose/finalize pattern

How to implement the Dispose pattern when my class contains a socket & event?

Should it be something like this?

class MyClass
{
   Socket m_ListenerSocket = new Socket();
   book m_Disposed=false;

   public void Dispose()
   {
      Dispose(true);
      GC.SuppressFinalize(this);
   }

   private void Dispose(bool isDisposing)
   {
      if (!m_Disposed)
      {
          if (isDisposing)
          {
              if (m_ListenerSocket != null)
              {
                   m_ListenerSocket.Dispose();
                   innerClass.Notify -= Notify;
              }
          }
        //finalized unmanged code here
        m_Disposed = true;
      }
  }

  ~MyClass()
  {
       Dispose(false);
  }
}

I'm confused... is socket class is "managed code c# version of winSock"? so it should be released in case of user called dispose ("isDisposing IS true") what about event handlers?

so at finalized comment section should free only Inptr objects? Thanks.

like image 208
roman Avatar asked Nov 13 '12 07:11

roman


People also ask

How do you use the dispose method?

The Dispose(bool) method overloadThe disposing parameter should be false when called from a finalizer, and true when called from the IDisposable. Dispose method. In other words, it is true when deterministically called and false when non-deterministically called.

What is Finalize and Dispose method in C#?

Finalize is the backstop method, called by the garbage collector when it reclaims an object. Dispose is the "deterministic cleanup" method, called by applications to release valuable native resources (window handles, database connections, etc.)

When to use Finalize and Dispose in net?

Microsoft recommends that we implement both Dispose and Finalize when working with unmanaged resources. The Finalize implementation would run and the resources would still be released when the object is garbage collected even if a developer neglected to call the Dispose method explicitly.

What Dispose method?

What Does Dispose Mean? In the context of C#, dispose is an object method invoked to execute code required for memory cleanup and release and reset unmanaged resources, such as file handles and database connections.


2 Answers

I think there are many ways to deal with disposable objects, regardless if they have events or not.

Is only a wild guess, but if you took a class from the .net framework and this class has a Dispose() method, you can pretty much say that it is managed code, so you are safe just to call the Dispose method instead of creating the destructor by yourself. This is rather obiquitous because as you see in my example below, you can also implement IDisposable interface in your own classes and then dispose your internal objects in a proper way.

Could this be helpful to you?

public class MyClassWithSocket :IDisposable 
{

    Socket myInternalSocket = null;

    public void methodThatUsesSocket()
    {
        using (var mySocket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream , ProtocolType.Tcp))
        {
        //do something with socket 
        //this will be disposed automatically

        }
    }

    public void methodThatUsesInternalSocket() 
    {
        myInternalSocket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
        //do other things
    }

    public static Socket SomethingThatReturnsSocket()
    {

        Socket tempSocket =  new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);

        return tempSocket;
    }


    public void Dispose()
    {
        myInternalSocket.Dispose();
    }
}
like image 72
Jorge Alvarado Avatar answered Nov 10 '22 09:11

Jorge Alvarado


Since Socket is a managed class, the guidelines for implementing IDisposable states that no Finalizer is needed. In fact, having a finalizer will actually cause the Garbage Collection of the object to be delayed, since it will call the finalizer during the first garbage collection and garbage collect the object the second time garbage collection is run.

Regarding the event you'll probably want to de-register from the event in the Dispose method, since the event subscription will cause innerClass to hold a reference to the instance of MyClass, unless the innerClass object is short lived. See this question for more info on events and Dispose.

I think that the following implementation would be enough for your scenario:

class MyClass : IDisposable
{
   Socket m_listenerSocket = new Socket();

   public void Dispose()
   {
       m_listenerSocket.Dispose();
       innerClass.Notify -= Notify; 
   }
}

The part in your code that you have commented with "finalized unmanged code here" should only release unmanaged resources, such as handles in the form of IntPtr, etc. Since the introduction of SafeHandle in .NET 2.0, you rarely need to do so, since you can wrap your IntPtr in aSafeHandle and then treat it as a managed resource.

like image 31
PHeiberg Avatar answered Nov 10 '22 10:11

PHeiberg