Is IDisposable.Dispose() called automatically? [duplicate]
Possible Duplicate:
Will the Garbage Collector call IDisposable.Dispose for me?
I have a Class which has s开发者_StackOverflowome unmanaged resources. My class implements the IDisposable
interface and releases the unmanaged resources in the Dispose()
method. Do I have to call the Dispose()
method or will it be automatically called somehow? Will the Garbage Collector call it?
Dispose()
will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable
provides a way for users of your class to release resources early, instead of waiting for the garbage collector.
The preferable way for a client is to use the using
statement which handles automatic calling of Dispose()
even if there are exceptions.
A proper implementation of IDisposable
is:
class MyClass : IDisposable
{
private bool disposed = false;
void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!disposed)
{
if(disposing)
{
// Manual release of managed resources.
}
// Release unmanaged resources.
disposed = true;
}
}
~MyClass() { Dispose(false); }
}
If the user of the class calls Dispose()
the cleanup takes place directly. If the object is catched by the garbage collector, it calls Dispose(false)
to do the cleanup. Please note that when called from the finalizer (the ~MyClass
method) managed references may be invalid, so only unmanaged resources can be released.
If you instantiate your object in a using
statement, Dispose() is called for you when code exits the using
block
using(var myObject = new MyDisposableObject())
{
blah();
} // Dispose() is called here (or whenever the code exits the block)
If you don't use using
, then it's up to you (the calling code) to dispose of your object by explicitely calling Dispose().
Also, you (the implementor of MyObject) can add support for a finalizer in case your caller doesn't call Dispose(). More info here.
You will have to call this method manually, maybe (assuming that "MyClass" implements "IDisposable") in a construct like
using(var myclass = new MyClass())
{
// do something with myclass
}
// now 'myclass'is Disposed
In C# 8.0, you can write as below statement:
using var myclass=new MyClass();
and the "myclass" will be disposed automatically at the end of the scope.
The advantage of the using
statement (compared to calling Dispose() explicitly) is that Dispose()
is called no matter how you exit this block: by running past the end, encountering a return
statement or having an exception thrown.
To make sure the resources are correctly disposed, you need to both implement IDisposable
and call Dispose
in the destructor(finalizer).
class Foo : IDisposable
{
private bool m_disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Foo()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (!m_disposed)
{
if (disposing)
{
//release managed resources
}
//release unmanaged resources
m_disposed = true;
}
}
}
精彩评论