* Dom said:
Thanks Felix. I think that;s exaxctly what I want. But can you help
me with one small point. I see that your pattern is the one suggested
as MS, but it seems like this is a simpler pattern.
[Just a C# "destructor" (finalizer)]
That seems easier, or am I missing something?
Sure it "looks" easier, but it has two drawbacks:
- The connection will be closed some time later, and this could quite
easily be a significant amount of time (whenever the garbage collector
tried to release the object and scheduled a finalizer thread).
- You suffer a performance overhead because the garbage collector cannot
release the object in the first attempt when it finds a finalizer that
has to be called. Instead, it has to create a thread (which is costly)
and after the finalizer was run, there will be a second attempt to
release the object.
Implementing IDisposable, you can avoid that by creating your object in
a using-block. When the block is left, Dispose() is called
automatically. Alternatively, you could call Dispose() yourself, but the
using-block is safer because it'll catch any way you might leave it (a
return statement, an exception, ...).
As a fallback, you still provide a finalizer, so if your caller misses
the using-block or the call to Dispose(), it gets called at
finalization. To avoid the overhead described above, you suppress
finalization if Dispose() was correctly called.
I'd suggest you also add a boolean member variable "disposed" that
serves as a flag for a disposed object. Most method calls will be
invalid after the object was disposed, so those method's implementations
should start with a line
| if (disposed) throw new ObjectDisposedException(
| "Object was already disposed.");
You can also use this flag to ignore double calls to Dispose().
Regards,
Felix
--
Felix Palmen (Zirias) + [PGP] Felix Palmen <
[email protected]>
web:
http://palmen-it.de/ |
http://palmen-it.de/pub.txt
my open source projects: | Fingerprint: ED9B 62D0 BE39 32F9 2488
http://palmen-it.de/?pg=pro + 5D0C 8177 9D80 5ECF F683