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.
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.
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.)
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 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.
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();
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With