I'm trying to make sure that my understanding of IDisposable
is correct and there's something I'm still not quite sure on.
IDisposable
seems to serve two purpose.
My confusion comes from identifying which scenarios have "unmanaged resources" in play.
Say you are using a Microsoft-supplied IDisposable
-implementing (managed) class (say, database or socket-related).
IDisposable
for just 1 or 1&2 above?Unmanaged resources are those that run outside the . NET runtime (CLR)(aka non-. NET code.) For example, a call to a DLL in the Win32 API, or a call to a . dll written in C++.
Managed resources are those that are pure . NET code and managed by the runtime and are under its direct control. Unmanaged resources are those that are not. File handles, pinned memory, COM objects, database connections etc.
Typically, types that use unmanaged resources implement the IDisposable or IAsyncDisposable interface to allow the unmanaged resources to be reclaimed. When you finish using an object that implements IDisposable, you call the object's Dispose or DisposeAsync implementation to explicitly perform cleanup.
- How do you know whether it is implementing IDisposable for just 1 or 1&2 above?
The answer to your first question is "you shouldn't need to know". If you're using third party code, then you are its mercy to some point - you'd have to trust that it's disposing of itself properly when you call Dispose on it. If you're unsure or you think there's a bug, you could always try using Reflector() to disassemble it (if possible) and check out what it's doing.
- Am I responsible for making sure that unmanaged resources it may or may not hold internally are freed? Should I be adding a finalizer (would that be the right mechanism?) to my own class that calls instanceOfMsSuppliedClass.Dispose()?
You should rarely, if ever, need to implement a finalizer for your classes if you're using .Net 2.0 or above. Finalizers add overhead to your class, and usually provide no more functionality then you'd need with just implementing Dispose. I would highly recommend visiting this article for a good overview on disposing properly. In your case, you would want to call instanceofMSSuppliedClass.Dispose()
in your own Dispose() method.
Ultimately, calling Dispose() on an object is good practice, because it explictly lets the GC know that you're done with the resource and allows the user the ability to clean it up immediately, and indirectly documents the code by letting other programmers know that the object is done with the resources at that point. But even if you forget to call it explicitly, it will happen eventually when the object is unrooted (.Net is a managed platform after all). Finalizers should only be implemented if your object has unmanaged resources that will need implicit cleanup (i.e. there is a chance the consumer can forget to clean it up, and that this will be problematic).
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