public class BaseResource: IDisposable
{
// Pointer to an external unmanaged resource.
private IntPtr handle;
// Other managed resource this class uses.
private Component Components;
private bool disposed = false;
public BaseResource()
{
// Insert appropriate constructor code here.
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
// Dispose managed resources.
Components.Dispose();
}
CloseHandle(handle);
handle = IntPtr.Zero;
}
disposed = true;
}
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
~BaseResource()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
// Allow your Dispose method to be called multiple times,
// but throw an exception if the object has been disposed.
// Whenever you do something with this class,
// check to see if it has been disposed.
public void DoSomething()
{
if(this.disposed)
{
throw new ObjectDisposedException();
}
}
}
Moje pitanja su
1. Sta ce se desiti sa unmanaged resursima kada GC finalizira objekat? Iz koda se vidi da ce se pozvati Dispose(false), i taj "false" ce zaobici granu koja oslobadja unmanaged resurse... Zasto se u finalizeru ne poziva Dispose(true). Neko bi mozda rekao "pa zato sto mozda drugi objekti koriste umanaged resurse koje je ovaj objekat kreirao/otvorio, cim ti nisi explicitno pozvao dispose GC ih ne dira", ali onda cleanup kod za takve shared non-managed resurse ne bi ni trebao da bude u Dispose metodi, cak stavise ne bi ni trebao da se kreira od strane tog objekta...
2. Zasto se onaj bool parametar zove "disposing"? Od MS-a sam navikao na skolska deskriptivna imena varijabli, ime tog parametra u odnosu na njegovu svrhu nema nikakvog smisla, ili ga ja ne vidim (prvo bi pomislio na osnovu imena da je to neki thread-safety parametar)
3. Komentar iznad destruktora kaze "This destructor will run only if the Dispose method does not get called."
Jel su time mislili na disposing kontrolnu varijablu koja se setuje posle Dispose poziva (u tom slucaju komentar nije tacan, jer ce se onda destruktor ipak izvrsiti, samo ce uleteti u Dispose gde nece uraditi nista zbog kontrolne varijable). Ili su mozda mislili da .net framework nece pozvati destruktor uopste, ako si ti negde vec pozvao Dispose (u tom slucaju bi jezik bio nekako vezan na ime metode sto mi se cini malo verovatno, ako i jeste onda je to idiotski reseno, isto kao i hard-coded vezivanje operatora "yield" za IEnumerator interfejs, i jos mnogo hardkodovanih .net gluposti)
EDIT: Tek sada sam video onaj GC.SupressFinalize, tako da je odgovor na #3 u sustini jasan...
[Ovu poruku je menjao _v!rus_ dana 24.06.2007. u 21:21 GMT+1]
[Ovu poruku je menjao _v!rus_ dana 25.06.2007. u 13:21 GMT+1]