1 | public class UnhandledStream : IDispose |
The dispose pattern consists of a simple method : Dispose.
It should clean any resource which is unmanaged by the Garbage Collector and why is that?
Any resource which is handled by the GC can be safely discarded - for example an allocated array:
1 | public void SomeFunc() |
The Garbage Collector is a mechanism of the C# Virtual Machine (Called Common Language Runtime) which has a responsibility to collect all Managed allocations - classes, arrays, lists, etc…
An array is a type of resource that will be collected by the GC.
There are resources which the GC doesn’t try to assume how to handle:
These Resources can’t be collected by the GC, therefore it’s up to us to clean them when the time is ready.
1 | public void SomeFunc() |
Using the Dispose pattern it’s very easy to clean it up:
1 | public void SomeFunc() |
1 | public void SomeFunc() |
The using keyword is the best way to handle an unmanaged resource.
Basically it’s a sugar syntax to the try-finally statement:
1 | public void SomeFunc() |
A rule of thumb is - Reduce scope and lifetime of resources.
C# allows another step in guaranteeing discarding unmanaged resource - Destructors or Finalizers.
1 | public class MySocket |
When the GC is trying to collect a finalized class it puts the instance into a finalization queue and a special thread goes and finalizes all the objects.
Because the finalization queue is holding the object - the instance isn’t actually deleted until the thread is activated.
There are issues with finalizers:
My advice:
Don’t use destructors unless you know what you do - it can create more harm than good.
Unlike C++ Destructors which are inherently good - in C# they aren’t designed for the best performance.
So be aware.
Happy disposing and Thanks for reading!