There are many questions SO asking how to detect IDisposable objects leak. It seems like the answer is "you can't".
I just checked with the most trivial test case, that FxCop 10.0 doesn't do it, ReSharper 4 with MSVS2010 doesn't do it.
This seems wrong to me, worse than memory leaks in C (for which at least we have established tools to detect).
I was thinking: Is it possible, using reflection and other obscure advanced techniques, that I can inject a check at runtime, in the finalizer to see whether Dispose
has been called?
How about magic tricks with WinDBG+SOS?
Even if there aren't existing tools to do it, I'd like to know whether this is theoretically possible (my C# isn't very sharp).
Ideas?
NOTE This question's title might have been misleading. The real question here should be whether a IDisposable
object has been Disposed()
properly. Getting disposed by the GC doesn't count since I regard that as a mistake.
Edit: Solution: .NET Memory Profiler does the job. We just need to spam several GC.Collect()
at the end of the program to enable our profiler to correctly pick up the stats.
While @Justin Niessner's recommendation works, I find that using a full blown profiler too heavy.
I created my home-brew solution: EyeDisposable. It instruments assemblies to detect when
Dispose
have not been called.You didn't search hard enough. There are plenty of .NET Memory Profilers out there that will look at your program as it runs and let you know where/how your memory is used (and what is leaking it).
I would check out any of the following:
Microsoft's CLR Memory Profiler (free)
RedGate ANTS Memory Profiler
JetBrain's DotTrace (includes code profiler as well)
SciTech .NET Memory Profiler
Update
SciTech's .NET Memory Profiler has a feature called 'Dispose Tracker' that fits the bill for the OP's request of tracking only the Dispose calls in their application.
you can do it, by adding a Finalizer to your IDisposable objects. In the finalizer, you can check whether the object has been disposed or not. If it hasn't been disposed, you can assert this, or write something to a log, or whatever.
You can factor this functionality into a base class -
Disposable
- for instance, which can be used as a template to implement the Disposable pattern for instance.Like this, for instance: