Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IDisposable, Finalizers and the definition of an unmanaged resource

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.

  1. To provide a convention to "shut down" a managed object on demand.
  2. To provide a convention to free "unmanaged resources" held by a managed object.

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).

  1. How do you know whether it is implementing IDisposable for just 1 or 1&2 above?
  2. Are you responsible for making sure that unmanaged resources it may or may not hold internally are freed? Should you be adding a finalizer (would that be the right mechanism?) to your own class that calls instanceOfMsSuppliedClass.Dispose()?
like image 891
xyz Avatar asked Jun 18 '09 15:06

xyz


People also ask

What is an unmanaged resource?

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++.

What are managed and unmanaged resources?

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.

What does it mean when an object implements IDisposable?

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.


1 Answers

  1. 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.

  1. 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).

like image 138
womp Avatar answered Sep 21 '22 12:09

womp