If a class has a property which contains unmanaged resources. How to make sure no memory leak when using the class
Class A
{
B {get; set;}
}
B contains unmanaged resources.
Implement IDisposable
and clean up your unmanaged resources by calling Dispose()
, preferably placing the call to Dispose
in a finally
statement so you clean up resources even in the case of an exception.
C# has a using
keyword that you can employ to make sure that the Dispose
method is called, even if an exception is thrown.
EDIT: Incorporated call to GC.SuppressFinalize and finalizer implementation per Ran's answer
class A : IDisposable
{
private bool _disposed;
~A()
{
this.Dispose(false);
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// dispose managed resources
}
// clean up unmanaged resources
_disposed = true;
}
}
}
class Program
{
static void Main(string[] args)
{
using (var someInstance = new A())
{
// do some things with the class.
// once the using block completes, Dispose
// someInstance.Dispose() will automatically
// be called
}
}
}
Using IDisposable
might not be enough, because it relies on the user remembering to call Dispose
or to use using
etc.
For a complete solution, combine IDisposable
and a finalizer. Like this:
Edit: Made some corrections in the Dispose method based on SpeksETC's comment.
class MyClass : IDisposable
{
~MyClass()
{
Dispose(false);
}
public void Dispose()
{
GC.SupressFinalize();
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (!disposing)
{
// clear unmanaged resources here (can only be called once)
...
}
// dispose called explicitly by the user, clean up managed resources here
...
}
}
This ensures that native resources will always be cleared, even if the user forgets to call Dispose
, while still allowing the user to clear the resources early.
The if
inside the Dispose
implementation is needed because if this class is being finalized, you may not call Dispose
on your members because they may have been GC'ed already.
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