Question: Question:
How do I implement IDisposable?
Answer: Answer:
If you want to implement a class that has some resources, you need to implement the IDisposable interface.
What is a resource -bearing class? <br /> If you could simply hold an IDisposable object in a field of that class,
It's a class that has some resources.
Also, even if it is not IDisposable, if there is an unmanaged part such as Win32API such as COM, it will be those resources.
How to implement IDisposable
class Test : IDisposable {
private bool disposed = false;
protected virtual void Dispose( bool disposing ) {
if( !disposed ) {
disposed = true;
// ここでフィールドとして保持してあるリソースを解放する。
if( disposing ) {
// マネージから呼ばれた場合は、ここを通る
GC.SuppressFinalize(this);
}
}
}
// ファイナライザ
~Test() {
Dispose( false );
}
public void Dispose() {
Dispose( true );
}
}
Implement this way so that the derived class overrides the Dispose method.
In that case, you must always call the base class's Dispose method.
Finalizer
If the finalizer is no longer referenced from anywhere without calling the Dispose method
Insurance for executing the Dispose method by GC (garbage collector).
You need to define a finalizer only if you have the effect of forgetting to call Dispose, such as when you have unmanaged resources.
However, if you define a finalizer, it will remain in memory longer than a normal object.
This is due to the GC specifications.
When defining a finalizer, you should call GC.SuppressFinalize (this) to inform the GC that you no longer need to call the finalizer if the managed code successfully executes the Dispose method.
Also, the finalizer runs in a thread dedicated to the finalizer.
Be careful when touching around the UI with Dispose.
About the disposed flag
This flag corresponds to the recall of the Dispose method.
The Dispose method should be designed to be called multiple times.
If multiple threads can be called at the same time, there is a way to use Interlocked.
private int disposed = 0;
protected virtual void Dispose( bool disposing ) {
if( Interlocked.CompareExchange( ref disposed , 1 , 0 ) == 0 ) {
if( disposing ) {
// TODO: マネージ状態を破棄します (マネージ オブジェクト)。
}
// ここでフィールドとして保持してあるリソースを解放する。
}
}