I have a number of classes which have private member variables that implement IDisposable (timers, brushes, etc). Do I need to do anything to ensure these variables are cleaned up properly by the .NET Framework?
The literature I've come across is referring to "managed resources" vs. "unmanaged resources". These terms are confusing to me because you can have a managed class which implements functionality using unmanaged resources. Is that considered an "unmanaged resource" or "managed resource" ?
My understanding is if you aren't calling Dispose() on an object that implements IDisposable, then the resources aren't being freed until the application exits. This situation could cause OutOfMemory exceptions when running the program for a long period of time.
How can I be sure my code is handling resource management correctly? It's important for these objects because they are custom controls and there may be a lot of drawing which consumes IDisposable resources. I use the C# using statement whenever I can, but sometimes I need to make an object implementing IDisposable a member variable, and the using statement won't help me there.
You have some good information and some misinformation in your understanding.
The long and short of it is that you need to
Dispose()
anything that implementsIDisposable
.Being as these are private member variables of your class, and if these are supposed to be available for the lifetime of instances of that class, your class should also implement
IDisposable
andDispose()
of those types in its ownDispose()
method.If those private member variables have a limited lifetime (i.e. only within one method), just wrap them in a
using
block.If your class has member variables that implement IDisposable, then your class should implement it as well. You clean up what you own.
Yes - if your class "contains" an
IDisposable
, that class should almost certainly implementIDisposable
too."Managed" resources are basically memory. "Unmanaged" resources can be file handles, network connections, handles to graphics objects etc. In most cases types which have direct access to native handles have finalizers, so the resource will be released at some point, but it's still better to release it explicitly - in some cases (such as with
HttpWebResponse
) there can be a limited number of such resources available (connections in a connection pool to a single host in this case) and you can end up timing out waiting for a "dead" resource to be freed.Where possible, it's nicer not to have such class members in the first place - have them as method parameters of local variables etc, so you can use them and then close them without tying the lifetime of the resource to the lifetime of your object. However, in some cases that's not appropriate - in which case you should implement
IDisposable
.Very comprehensive IDisposable guidelines are here.
'Unmanaged resource' usually refers to cases where your code refernces native handles directly (file handles, connections, sockets etc). In this case you would also have to implement finalizer or use SafeHandle. Most of the time you reference native handles indirectly, through .NET classes like TextReader. In this case you can simply use 'using' or, if you are writing library, implement IDisposable transitively.
Three simple rules.
A managed resource is anything implementing
IDisposable
. An unmanaged resource is something like aHANDLE
that you got via p/Invoke. A class likeSafeHandle
(or one derived fromSafeHandle
) owns an unmanaged resource, but it is considered a managed resource itself. So any class that owns unmanaged resource is itself a managed resource.Since you have a class owning managed resources, follow Rule 2: implement
IDisposable
(but not a finalizer).IDisposable
allows for earlier cleanup. If you don't call it, the resources will be cleaned up anyway (they won't hang around until process exit); they'll just be cleaned up later, and you don't have a choice about when they get cleaned up.1) You can use a Memory Profiler Tool, there are plenty around the web, the best i know being Reg Gate's ANTS Profiler.
2) My rule of thumb is that events must always be unsubscribed, and disposable objects (Streams etc) will be disposed automatically if they're member variables and the object holding them gets destroyed. If you create a local disposable object in a method for example, you must dispose it, or just put it in a
using
statement and forget about it ;)