Advise needed to complete Dispose/Finalize - c#

Following is a stripped-down version of c# code, which helps to capture the PrintScreen key. This work as I expected and tested.
Question: I am aware of deterministic destruction/disposal pattern, which I started to draft as below. However, I need some expert advice to complete my dispose and finalize method. Any advise ?
public class RegisterPrintKey : IDisposable
{
public delegate void HotKeyPass();
public event HotKeyPass HotKey;
private IntPtr m_WindowHandle = IntPtr.Zero;
private MKEY m_ModKey = MKEY.MOD_CONTROL;
private Keys m_Keys = Keys.A;
private HotKeyWndProc m_HotKeyWnd = new HotKeyWndProc();
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr wnd, int id, MKEY mode, Keys vk);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr wnd, int id);
private class HotKeyWndProc : NativeWindow
{
public int m_WParam = 10000;
public HotKeyPass m_HotKeyPass;
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312 && m.WParam.ToInt32() == m_WParam)
{
if (m_HotKeyPass != null) m_HotKeyPass.Invoke();
}
base.WndProc(ref m);
}
}
private bool hasDisposed = false;
protected virtual void Dispose(bool dispose)
{
if (hasDisposed) return;
if (dispose)
{
//release objects owned by this instance
HotKey = null;
hasDisposed=true;
}
m_WindowHandle = IntPtr.Zero; // I presume this is not required.
m_Keys = null; //Do i need to dispose this or relay on stack ( clean up when thread unwind its stack)
m_ModKey = null;
m_HotKeyWnd.DestroyHandle();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~RegisterPrintKey()
{
Dispose(false);
}
}
public enum MKEY
{
MOD_ALT = 0x0001,
MOD_CONTROL = 0x0002,
MOD_SHIFT = 0x0004,
MOD_WIN = 0x0008,
}

Some suggestions on your code
public class RegisterPrintKey : IDisposable {
...
// This class can allocate the Window Handle resource (HWND)
private class HotKeyWndProc : NativeWindow {
}
// Explicit resource (HWND) allocation
private HotKeyWndProc m_HotKeyWnd = new HotKeyWndProc();
// I'd rather make a property from your "hasDisposed" field:
// - it's make easier to check instance's state (esp. while debugging)
// - IsDisposed is more popular name for this
public Boolean IsDisposed {
get;
protected set; // <- or even "private set"
}
protected virtual void Dispose(Boolean dispose) {
if (IsDisposed)
return;
if (disposed) {
// Release any Objects here
// You've allocated the HWND resource so you have to dispose it:
m_HotKeyWnd.DestroyHandle(); // <- Free HWND you've created
}
// Here, you may work with structures only!
// You don't need these assignments, but you can safely do them:
// mayhaps, they'll be useful for you while debugging
m_WindowHandle = IntPtr.Zero;
m_Keys = null;
m_ModKey = null;
// Finally, we've done with disposing the instance
IsDisposed = true;
}
public void Dispose() {
Dispose(true);
// We've done with Dispose: "GC, please, don't bother the disposed instance"
GC.SuppressFinalize(this);
}
// A treacherous enemy I've commented out:
// if you've made a error in Dispose() it'll be resource leak
// or something like AccessViolation. The only good thing is that
// you can easily reproduce (and fix) the problem.
// If you've uncommented ~RegisterPrintKey() this leak/EAV will become
// floating error: it'll appear and disappear on different workstations
// OSs etc: you can't control GC when to run. Floating error is
// much harder to detect.
// Another bad issue with finalizer is that it prevents the instance
// from being in zero generation, see
// http://stackoverflow.com/questions/12991692/why-doesnt-object-with-finalizer-get-collected-even-if-it-is-unrooted
//~RegisterPrintKey() {
// // This code can be called (if called!) at random time
// Dispose(false); // <- That's an enemy!
// }
}

The basic idea is not to touch anything managed in the Dispose(false) variant of your method. Also, there's usually no need to explicitly set anything to null (especially in the Dispose(false) variant, where those objects are probably already garbage collected).
So, you've got the basic pattern right, but you don't need to do anything in Dispose(false) except for the m_HotKeyWnd.DestroyHandle().
To explain a bit more, when the finalizer code is run by the garbage collector, all of the other managed objects referenced by this object (that aren't referenced by others) are probably garbage collected already. Ignore everything that's managed in the finalizer, it probably doesn't even exist anymore. It's also something you can expect in the native callback (ie. your WndProc in this case) - it's very much possible that the managed objects you interact with don't exist anymore, if the callback comes while the object is on the finalizer queue. This is a fairly common cause of application crashes (or at least of unexpected exceptions) in a managed application interacting with native code.
So, Dispose(true) should handle everything you want to clean up, managed and unmanaged (and you're correctly using GC.SuppressFinalize - you've already disposed of the unmanaged resources, so there's no need for GC to put your object on the finalizer queue), Dispose(false) should only ever handle the unmanaged bits.
EDIT: I didn't realize that your m_HotKeyWnd is actually a managed object - it takes care of its unmanaged resources on its own, and you should in no case call its DestroyHandle from the finalizer. In fact, you don't even need the finalizer, its completely redundant (and thus, slightly harmful). Just implement a simple Dispose (instead of the usual finalizer-dispose pattern) that disposes of the m_HotKeyWnd and sets it to null (NullReferenceException is better in this case than AccessViolationException or undefined behaviour you could get when using the object after its been disposed of - unmanaged stuff gets tricky fast), and does nothing else.

Related

If you derive from a class which has interface IDispose, do you need to implement Dispose? [duplicate]

C# 2008
I have been working on this for a while now, and I am still confused about the use of finalize and dispose methods in code. My questions are below:
I know that we only need a finalizer while disposing unmanaged resources. However, if there are managed resources that make calls to unmanaged resources, would it still need to implement a finalizer?
However, if I develop a class that doesn't use any unmanaged resource - directly or indirectly, should I implement the IDisposable to allow the clients of that class to use the 'using statement'?
Would it be feasible to implement IDisposable just to enable clients of your class to use the using statement?
using(myClass objClass = new myClass())
{
// Do stuff here
}
I have developed this simple code below to demonstrate the Finalize/dispose use:
public class NoGateway : IDisposable
{
private WebClient wc = null;
public NoGateway()
{
wc = new WebClient();
wc.DownloadStringCompleted += wc_DownloadStringCompleted;
}
// Start the Async call to find if NoGateway is true or false
public void NoGatewayStatus()
{
// Start the Async's download
// Do other work here
wc.DownloadStringAsync(new Uri(www.xxxx.xxx));
}
private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
// Do work here
}
// Dispose of the NoGateway object
public void Dispose()
{
wc.DownloadStringCompleted -= wc_DownloadStringCompleted;
wc.Dispose();
GC.SuppressFinalize(this);
}
}
Question about the source code:
Here I have not added the finalizer, and normally the finalizer will be called by the GC, and the finalizer will call the Dispose. As I don't have the finalizer, when do I call the Dispose method? Is it the client of the class that has to call it?
So my class in the example is called NoGateway and the client could use and dispose of the class like this:
using(NoGateway objNoGateway = new NoGateway())
{
// Do stuff here
}
Would the Dispose method be automatically called when execution reaches the end of the using block, or does the client have to manually call the dispose method? i.e.
NoGateway objNoGateway = new NoGateway();
// Do stuff with object
objNoGateway.Dispose(); // finished with it
I am using the WebClient class in my NoGateway class. Because WebClient implements the IDisposable interface, does this mean that WebClient indirectly uses unmanaged resources? Is there a hard and fast rule to follow this? How do I know that a class uses unmanaged resources?
The recommended IDisposable pattern is here. When programming a class that uses IDisposable, generally you should use two patterns:
When implementing a sealed class that doesn't use unmanaged resources, you simply implement a Dispose method as with normal interface implementations:
public sealed class A : IDisposable
{
public void Dispose()
{
// get rid of managed resources, call Dispose on member variables...
}
}
When implementing an unsealed class, do it like this:
public class B : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// get rid of managed resources
}
// get rid of unmanaged resources
}
// only if you use unmanaged resources directly in B
//~B()
//{
// Dispose(false);
//}
}
Notice that I haven't declared a finalizer in B; you should only implement a finalizer if you have actual unmanaged resources to dispose. The CLR deals with finalizable objects differently to non-finalizable objects, even if SuppressFinalize is called.
So, you shouldn't declare a finalizer unless you have to, but you give inheritors of your class a hook to call your Dispose and implement a finalizer themselves if they use unmanaged resources directly:
public class C : B
{
private IntPtr m_Handle;
protected override void Dispose(bool disposing)
{
if (disposing)
{
// get rid of managed resources
}
ReleaseHandle(m_Handle);
base.Dispose(disposing);
}
~C() {
Dispose(false);
}
}
If you're not using unmanaged resources directly (SafeHandle and friends doesn't count, as they declare their own finalizers), then don't implement a finalizer, as the GC deals with finalizable classes differently, even if you later suppress the finalizer. Also note that, even though B doesn't have a finalizer, it still calls SuppressFinalize to correctly deal with any subclasses that do implement a finalizer.
When a class implements the IDisposable interface, it means that somewhere there are some unmanaged resources that should be got rid of when you've finished using the class. The actual resources are encapsulated within the classes; you don't need to explicitly delete them. Simply calling Dispose() or wrapping the class in a using(...) {} will make sure any unmanaged resources are got rid of as necessary.
The official pattern to implement IDisposable is hard to understand. I believe this one is better:
public class BetterDisposableClass : IDisposable {
public void Dispose() {
CleanUpManagedResources();
CleanUpNativeResources();
GC.SuppressFinalize(this);
}
protected virtual void CleanUpManagedResources() {
// ...
}
protected virtual void CleanUpNativeResources() {
// ...
}
~BetterDisposableClass() {
CleanUpNativeResources();
}
}
An even better solution is to have a rule that you always have to create a wrapper class for any unmanaged resource that you need to handle:
public class NativeDisposable : IDisposable {
public void Dispose() {
CleanUpNativeResource();
GC.SuppressFinalize(this);
}
protected virtual void CleanUpNativeResource() {
// ...
}
~NativeDisposable() {
CleanUpNativeResource();
}
}
With SafeHandle and its derivatives, these classes should be very rare.
The result for disposable classes that don't deal directly with unmanaged resources, even in the presence of inheritance, is powerful: they don't need to be concerned with unmanaged resources anymore. They'll be simple to implement and to understand:
public class ManagedDisposable : IDisposable {
public virtual void Dispose() {
// dispose of managed resources
}
}
Note that any IDisposable implementation should follow the below pattern (IMHO). I developed this pattern based on info from several excellent .NET "gods" the .NET Framework Design Guidelines (note that MSDN does not follow this for some reason!). The .NET Framework Design Guidelines were written by Krzysztof Cwalina (CLR Architect at the time) and Brad Abrams (I believe the CLR Program Manager at the time) and Bill Wagner ([Effective C#] and [More Effective C#] (just take a look for these on Amazon.com:
Note that you should NEVER implement a Finalizer unless your class directly contains (not inherits) UNmanaged resources. Once you implement a Finalizer in a class, even if it is never called, it is guaranteed to live for an extra collection. It is automatically placed on the Finalization Queue (which runs on a single thread). Also, one very important note...all code executed within a Finalizer (should you need to implement one) MUST be thread-safe AND exception-safe! BAD things will happen otherwise...(i.e. undetermined behavior and in the case of an exception, a fatal unrecoverable application crash).
The pattern I've put together (and written a code snippet for) follows:
#region IDisposable implementation
//TODO remember to make this class inherit from IDisposable -> $className$ : IDisposable
// Default initialization for a bool is 'false'
private bool IsDisposed { get; set; }
/// <summary>
/// Implementation of Dispose according to .NET Framework Design Guidelines.
/// </summary>
/// <remarks>Do not make this method virtual.
/// A derived class should not be able to override this method.
/// </remarks>
public void Dispose()
{
Dispose( true );
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
// Always use SuppressFinalize() in case a subclass
// of this type implements a finalizer.
GC.SuppressFinalize( this );
}
/// <summary>
/// Overloaded Implementation of Dispose.
/// </summary>
/// <param name="isDisposing"></param>
/// <remarks>
/// <para><list type="bulleted">Dispose(bool isDisposing) executes in two distinct scenarios.
/// <item>If <paramref name="isDisposing"/> equals true, the method has been called directly
/// or indirectly by a user's code. Managed and unmanaged resources
/// can be disposed.</item>
/// <item>If <paramref name="isDisposing"/> equals false, the method has been called by the
/// runtime from inside the finalizer and you should not reference
/// other objects. Only unmanaged resources can be disposed.</item></list></para>
/// </remarks>
protected virtual void Dispose( bool isDisposing )
{
// TODO If you need thread safety, use a lock around these
// operations, as well as in your methods that use the resource.
try
{
if( !this.IsDisposed )
{
if( isDisposing )
{
// TODO Release all managed resources here
$end$
}
// TODO Release all unmanaged resources here
// TODO explicitly set root references to null to expressly tell the GarbageCollector
// that the resources have been disposed of and its ok to release the memory allocated for them.
}
}
finally
{
// explicitly call the base class Dispose implementation
base.Dispose( isDisposing );
this.IsDisposed = true;
}
}
//TODO Uncomment this code if this class will contain members which are UNmanaged
//
///// <summary>Finalizer for $className$</summary>
///// <remarks>This finalizer will run only if the Dispose method does not get called.
///// It gives your base class the opportunity to finalize.
///// DO NOT provide finalizers in types derived from this class.
///// All code executed within a Finalizer MUST be thread-safe!</remarks>
// ~$className$()
// {
// Dispose( false );
// }
#endregion IDisposable implementation
Here is the code for implementing IDisposable in a derived class. Note that you do not need to explicitly list inheritance from IDisposable in the definition of the derived class.
public DerivedClass : BaseClass, IDisposable (remove the IDisposable because it is inherited from BaseClass)
protected override void Dispose( bool isDisposing )
{
try
{
if ( !this.IsDisposed )
{
if ( isDisposing )
{
// Release all managed resources here
}
}
}
finally
{
// explicitly call the base class Dispose implementation
base.Dispose( isDisposing );
}
}
I've posted this implementation on my blog at: How to Properly Implement the Dispose Pattern
I agree with pm100 (and should have explicitly said this in my earlier post).
You should never implement IDisposable in a class unless you need it. To be very specific, there are about 5 times when you would ever need/should implement IDisposable:
Your class explicitly contains (i.e. not via inheritance) any managed resources which implement IDisposable and should be cleaned up once your class is no longer used. For example, if your class contains an instance of a Stream, DbCommand, DataTable, etc.
Your class explicitly contains any managed resources which implement a Close() method - e.g. IDataReader, IDbConnection, etc. Note that some of these classes do implement IDisposable by having Dispose() as well as a Close() method.
Your class explicitly contains an unmanaged resource - e.g. a COM object, pointers (yes, you can use pointers in managed C# but they must be declared in 'unsafe' blocks, etc.
In the case of unmanaged resources, you should also make sure to call System.Runtime.InteropServices.Marshal.ReleaseComObject() on the RCW. Even though the RCW is, in theory, a managed wrapper, there is still reference counting going on under the covers.
If your class subscribes to events using strong references. You need to unregister/detach yourself from the events. Always to make sure these are not null first before trying to unregister/detach them!.
Your class contains any combination of the above...
A recommended alternative to working with COM objects and having to use Marshal.ReleaseComObject() is to use the System.Runtime.InteropServices.SafeHandle class.
The BCL (Base Class Library Team) has a good blog post about it here http://blogs.msdn.com/bclteam/archive/2005/03/16/396900.aspx
One very important note to make is that if you are working with WCF and cleaning up resources, you should ALMOST ALWAYS avoid the 'using' block. There are plenty of blog posts out there and some on MSDN about why this is a bad idea. I have also posted about it here - Don't use 'using()' with a WCF proxy
Using lambdas instead of IDisposable.
I have never been thrilled with the whole using/IDisposable idea. The problem is that it requires the caller to:
know that they must use IDisposable
remember to use 'using'.
My new preferred method is to use a factory method and a lambda instead
Imagine I want to do something with a SqlConnection (something that should be wrapped in a using). Classically you would do
using (Var conn = Factory.MakeConnection())
{
conn.Query(....);
}
New way
Factory.DoWithConnection((conn)=>
{
conn.Query(...);
}
In the first case the caller could simply not use the using syntax. IN the second case the user has no choice. There is no method that creates a SqlConnection object, the caller must invoke DoWithConnection.
DoWithConnection looks like this
void DoWithConnection(Action<SqlConnection> action)
{
using (var conn = MakeConnection())
{
action(conn);
}
}
MakeConnection is now private
nobody answered the question about whether you should implement IDisposable even though you dont need it.
Short answer : No
Long answer:
This would allow a consumer of your class to use 'using'. The question I would ask is - why would they do it? Most devs will not use 'using' unless they know that they must - and how do they know. Either
its obviuos the them from experience (a socket class for example)
its documented
they are cautious and can see that the class implements IDisposable
So by implementing IDisposable you are telling devs (at least some) that this class wraps up something that must be released. They will use 'using' - but there are other cases where using is not possible (the scope of object is not local); and they will have to start worrying about the lifetime of the objects in those other cases - I would worry for sure. But this is not necessary
You implement Idisposable to enable them to use using, but they wont use using unless you tell them to.
So dont do it
Dispose pattern:
public abstract class DisposableObject : IDisposable
{
public bool Disposed { get; private set;}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~DisposableObject()
{
Dispose(false);
}
private void Dispose(bool disposing)
{
if (!Disposed)
{
if (disposing)
{
DisposeManagedResources();
}
DisposeUnmanagedResources();
Disposed = true;
}
}
protected virtual void DisposeManagedResources() { }
protected virtual void DisposeUnmanagedResources() { }
}
Example of inheritance:
public class A : DisposableObject
{
public Component components_a { get; set; }
private IntPtr handle_a;
protected override void DisposeManagedResources()
{
try
{
Console.WriteLine("A_DisposeManagedResources");
components_a.Dispose();
components_a = null;
}
finally
{
base.DisposeManagedResources();
}
}
protected override void DisposeUnmanagedResources()
{
try
{
Console.WriteLine("A_DisposeUnmanagedResources");
CloseHandle(handle_a);
handle_a = IntPtr.Zero;
}
finally
{
base.DisposeUnmanagedResources();
}
}
}
public class B : A
{
public Component components_b { get; set; }
private IntPtr handle_b;
protected override void DisposeManagedResources()
{
try
{
Console.WriteLine("B_DisposeManagedResources");
components_b.Dispose();
components_b = null;
}
finally
{
base.DisposeManagedResources();
}
}
protected override void DisposeUnmanagedResources()
{
try
{
Console.WriteLine("B_DisposeUnmanagedResources");
CloseHandle(handle_b);
handle_b = IntPtr.Zero;
}
finally
{
base.DisposeUnmanagedResources();
}
}
}
If you are using other managed objects that are using unmanaged resources, it is not your responsibility to ensure those are finalized. Your responsibility is to call Dispose on those objects when Dispose is called on your object, and it stops there.
If your class doesn't use any scarce resources, I fail to see why you would make your class implement IDisposable. You should only do so if you're:
Know you will have scarce resources in your objects soon, just not now (and I mean that as in "we're still developing, it will be here before we're done", not as in "I think we'll need this")
Using scarce resources
Yes, the code that uses your code must call the Dispose method of your object. And yes, the code that uses your object can use using as you've shown.
(2 again?) It is likely that the WebClient uses either unmanaged resources, or other managed resources that implement IDisposable. The exact reason, however, is not important. What is important is that it implements IDisposable, and so it falls on you to act upon that knowledge by disposing of the object when you're done with it, even if it turns out WebClient uses no other resources at all.
Some aspects of another answer are slightly incorrect for 2 reasons:
First,
using(NoGateway objNoGateway = new NoGateway())
actually is equivalent to:
try
{
NoGateway = new NoGateway();
}
finally
{
if(NoGateway != null)
{
NoGateway.Dispose();
}
}
This may sound ridiculous since the 'new' operator should never return 'null' unless you have an OutOfMemory exception. But consider the following cases:
1. You call a FactoryClass that returns an IDisposable resource or
2. If you have a type that may or may not inherit from IDisposable depending on its implementation - remember that I've seen the IDisposable pattern implemented incorrectly many times at many clients where developers just add a Dispose() method without inheriting from IDisposable (bad, bad, bad). You could also have the case of an IDisposable resource being returned from a property or method (again bad, bad, bad - don't 'give away your IDisposable resources)
using(IDisposable objNoGateway = new NoGateway() as IDisposable)
{
if (NoGateway != null)
{
...
If the 'as' operator returns null (or property or method returning the resource), and your code in the 'using' block protects against 'null', your code will not blow up when trying to call Dispose on a null object because of the 'built-in' null check.
The second reason your reply is not accurate is because of the following stmt:
A finalizer is called upon the GC destroying your object
First, Finalization (as well as GC itself) is non-deterministic. THe CLR determines when it will call a finalizer. i.e. the developer/code has no idea. If the IDisposable pattern is implemented correctly (as I've posted above) and GC.SuppressFinalize() has been called, the the Finalizer will NOT be called. This is one of the big reasons to properly implement the pattern correctly. Since there is only 1 Finalizer thread per managed process, regardless of the number of logical processors, you can easily degrade performance by backing up or even hanging the Finalizer thread by forgetting to call GC.SuppressFinalize().
I've posted a correct implementation of the Dispose Pattern on my blog: How to Properly Implement the Dispose Pattern
1) WebClient is a managed type, so you don't need a finalizer. The finalizer is needed in the case your users don't Dispose() of your NoGateway class and the native type (which is not collected by the GC) needs to be cleaned up after. In this case, if the user doesn't call Dispose(), the contained WebClient will be disposed by the GC right after the NoGateway does.
2) Indirectly yes, but you shouldn't have to worry about it. Your code is correct as stands and you cannot prevent your users from forgetting to Dispose() very easily.
Pattern from msdn
public class BaseResource: IDisposable
{
private IntPtr handle;
private Component Components;
private bool disposed = false;
public BaseResource()
{
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
Components.Dispose();
}
CloseHandle(handle);
handle = IntPtr.Zero;
}
disposed = true;
}
~BaseResource()
{ Dispose(false);
}
public void DoSomething()
{
if(this.disposed)
{
throw new ObjectDisposedException();
}
}
}
public class MyResourceWrapper: BaseResource
{
private ManagedResource addedManaged;
private NativeResource addedNative;
private bool disposed = false;
public MyResourceWrapper()
{
}
protected override void Dispose(bool disposing)
{
if(!this.disposed)
{
try
{
if(disposing)
{
addedManaged.Dispose();
}
CloseHandle(addedNative);
this.disposed = true;
}
finally
{
base.Dispose(disposing);
}
}
}
}
using(NoGateway objNoGateway = new NoGateway())
is equivalent to
try
{
NoGateway = new NoGateway();
}
finally
{
NoGateway.Dispose();
}
A finalizer is called upon the GC destroying your object. This can be at a totally different time than when you leave your method. The Dispose of IDisposable is called immediately after you leave the using block. Hence the pattern is usually to use using to free ressources immediately after you don't need them anymore.
From what I know, it's highly recommended NOT to use the Finalizer / Destructor:
public ~MyClass() {
//dont use this
}
Mostly, this is due to not knowing when or IF it will be called. The dispose method is much better, especially if you us using or dispose directly.
using is good. use it :)

Refactoring global object that implements IDisposable [duplicate]

C# 2008
I have been working on this for a while now, and I am still confused about the use of finalize and dispose methods in code. My questions are below:
I know that we only need a finalizer while disposing unmanaged resources. However, if there are managed resources that make calls to unmanaged resources, would it still need to implement a finalizer?
However, if I develop a class that doesn't use any unmanaged resource - directly or indirectly, should I implement the IDisposable to allow the clients of that class to use the 'using statement'?
Would it be feasible to implement IDisposable just to enable clients of your class to use the using statement?
using(myClass objClass = new myClass())
{
// Do stuff here
}
I have developed this simple code below to demonstrate the Finalize/dispose use:
public class NoGateway : IDisposable
{
private WebClient wc = null;
public NoGateway()
{
wc = new WebClient();
wc.DownloadStringCompleted += wc_DownloadStringCompleted;
}
// Start the Async call to find if NoGateway is true or false
public void NoGatewayStatus()
{
// Start the Async's download
// Do other work here
wc.DownloadStringAsync(new Uri(www.xxxx.xxx));
}
private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
// Do work here
}
// Dispose of the NoGateway object
public void Dispose()
{
wc.DownloadStringCompleted -= wc_DownloadStringCompleted;
wc.Dispose();
GC.SuppressFinalize(this);
}
}
Question about the source code:
Here I have not added the finalizer, and normally the finalizer will be called by the GC, and the finalizer will call the Dispose. As I don't have the finalizer, when do I call the Dispose method? Is it the client of the class that has to call it?
So my class in the example is called NoGateway and the client could use and dispose of the class like this:
using(NoGateway objNoGateway = new NoGateway())
{
// Do stuff here
}
Would the Dispose method be automatically called when execution reaches the end of the using block, or does the client have to manually call the dispose method? i.e.
NoGateway objNoGateway = new NoGateway();
// Do stuff with object
objNoGateway.Dispose(); // finished with it
I am using the WebClient class in my NoGateway class. Because WebClient implements the IDisposable interface, does this mean that WebClient indirectly uses unmanaged resources? Is there a hard and fast rule to follow this? How do I know that a class uses unmanaged resources?
The recommended IDisposable pattern is here. When programming a class that uses IDisposable, generally you should use two patterns:
When implementing a sealed class that doesn't use unmanaged resources, you simply implement a Dispose method as with normal interface implementations:
public sealed class A : IDisposable
{
public void Dispose()
{
// get rid of managed resources, call Dispose on member variables...
}
}
When implementing an unsealed class, do it like this:
public class B : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// get rid of managed resources
}
// get rid of unmanaged resources
}
// only if you use unmanaged resources directly in B
//~B()
//{
// Dispose(false);
//}
}
Notice that I haven't declared a finalizer in B; you should only implement a finalizer if you have actual unmanaged resources to dispose. The CLR deals with finalizable objects differently to non-finalizable objects, even if SuppressFinalize is called.
So, you shouldn't declare a finalizer unless you have to, but you give inheritors of your class a hook to call your Dispose and implement a finalizer themselves if they use unmanaged resources directly:
public class C : B
{
private IntPtr m_Handle;
protected override void Dispose(bool disposing)
{
if (disposing)
{
// get rid of managed resources
}
ReleaseHandle(m_Handle);
base.Dispose(disposing);
}
~C() {
Dispose(false);
}
}
If you're not using unmanaged resources directly (SafeHandle and friends doesn't count, as they declare their own finalizers), then don't implement a finalizer, as the GC deals with finalizable classes differently, even if you later suppress the finalizer. Also note that, even though B doesn't have a finalizer, it still calls SuppressFinalize to correctly deal with any subclasses that do implement a finalizer.
When a class implements the IDisposable interface, it means that somewhere there are some unmanaged resources that should be got rid of when you've finished using the class. The actual resources are encapsulated within the classes; you don't need to explicitly delete them. Simply calling Dispose() or wrapping the class in a using(...) {} will make sure any unmanaged resources are got rid of as necessary.
The official pattern to implement IDisposable is hard to understand. I believe this one is better:
public class BetterDisposableClass : IDisposable {
public void Dispose() {
CleanUpManagedResources();
CleanUpNativeResources();
GC.SuppressFinalize(this);
}
protected virtual void CleanUpManagedResources() {
// ...
}
protected virtual void CleanUpNativeResources() {
// ...
}
~BetterDisposableClass() {
CleanUpNativeResources();
}
}
An even better solution is to have a rule that you always have to create a wrapper class for any unmanaged resource that you need to handle:
public class NativeDisposable : IDisposable {
public void Dispose() {
CleanUpNativeResource();
GC.SuppressFinalize(this);
}
protected virtual void CleanUpNativeResource() {
// ...
}
~NativeDisposable() {
CleanUpNativeResource();
}
}
With SafeHandle and its derivatives, these classes should be very rare.
The result for disposable classes that don't deal directly with unmanaged resources, even in the presence of inheritance, is powerful: they don't need to be concerned with unmanaged resources anymore. They'll be simple to implement and to understand:
public class ManagedDisposable : IDisposable {
public virtual void Dispose() {
// dispose of managed resources
}
}
Note that any IDisposable implementation should follow the below pattern (IMHO). I developed this pattern based on info from several excellent .NET "gods" the .NET Framework Design Guidelines (note that MSDN does not follow this for some reason!). The .NET Framework Design Guidelines were written by Krzysztof Cwalina (CLR Architect at the time) and Brad Abrams (I believe the CLR Program Manager at the time) and Bill Wagner ([Effective C#] and [More Effective C#] (just take a look for these on Amazon.com:
Note that you should NEVER implement a Finalizer unless your class directly contains (not inherits) UNmanaged resources. Once you implement a Finalizer in a class, even if it is never called, it is guaranteed to live for an extra collection. It is automatically placed on the Finalization Queue (which runs on a single thread). Also, one very important note...all code executed within a Finalizer (should you need to implement one) MUST be thread-safe AND exception-safe! BAD things will happen otherwise...(i.e. undetermined behavior and in the case of an exception, a fatal unrecoverable application crash).
The pattern I've put together (and written a code snippet for) follows:
#region IDisposable implementation
//TODO remember to make this class inherit from IDisposable -> $className$ : IDisposable
// Default initialization for a bool is 'false'
private bool IsDisposed { get; set; }
/// <summary>
/// Implementation of Dispose according to .NET Framework Design Guidelines.
/// </summary>
/// <remarks>Do not make this method virtual.
/// A derived class should not be able to override this method.
/// </remarks>
public void Dispose()
{
Dispose( true );
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
// Always use SuppressFinalize() in case a subclass
// of this type implements a finalizer.
GC.SuppressFinalize( this );
}
/// <summary>
/// Overloaded Implementation of Dispose.
/// </summary>
/// <param name="isDisposing"></param>
/// <remarks>
/// <para><list type="bulleted">Dispose(bool isDisposing) executes in two distinct scenarios.
/// <item>If <paramref name="isDisposing"/> equals true, the method has been called directly
/// or indirectly by a user's code. Managed and unmanaged resources
/// can be disposed.</item>
/// <item>If <paramref name="isDisposing"/> equals false, the method has been called by the
/// runtime from inside the finalizer and you should not reference
/// other objects. Only unmanaged resources can be disposed.</item></list></para>
/// </remarks>
protected virtual void Dispose( bool isDisposing )
{
// TODO If you need thread safety, use a lock around these
// operations, as well as in your methods that use the resource.
try
{
if( !this.IsDisposed )
{
if( isDisposing )
{
// TODO Release all managed resources here
$end$
}
// TODO Release all unmanaged resources here
// TODO explicitly set root references to null to expressly tell the GarbageCollector
// that the resources have been disposed of and its ok to release the memory allocated for them.
}
}
finally
{
// explicitly call the base class Dispose implementation
base.Dispose( isDisposing );
this.IsDisposed = true;
}
}
//TODO Uncomment this code if this class will contain members which are UNmanaged
//
///// <summary>Finalizer for $className$</summary>
///// <remarks>This finalizer will run only if the Dispose method does not get called.
///// It gives your base class the opportunity to finalize.
///// DO NOT provide finalizers in types derived from this class.
///// All code executed within a Finalizer MUST be thread-safe!</remarks>
// ~$className$()
// {
// Dispose( false );
// }
#endregion IDisposable implementation
Here is the code for implementing IDisposable in a derived class. Note that you do not need to explicitly list inheritance from IDisposable in the definition of the derived class.
public DerivedClass : BaseClass, IDisposable (remove the IDisposable because it is inherited from BaseClass)
protected override void Dispose( bool isDisposing )
{
try
{
if ( !this.IsDisposed )
{
if ( isDisposing )
{
// Release all managed resources here
}
}
}
finally
{
// explicitly call the base class Dispose implementation
base.Dispose( isDisposing );
}
}
I've posted this implementation on my blog at: How to Properly Implement the Dispose Pattern
I agree with pm100 (and should have explicitly said this in my earlier post).
You should never implement IDisposable in a class unless you need it. To be very specific, there are about 5 times when you would ever need/should implement IDisposable:
Your class explicitly contains (i.e. not via inheritance) any managed resources which implement IDisposable and should be cleaned up once your class is no longer used. For example, if your class contains an instance of a Stream, DbCommand, DataTable, etc.
Your class explicitly contains any managed resources which implement a Close() method - e.g. IDataReader, IDbConnection, etc. Note that some of these classes do implement IDisposable by having Dispose() as well as a Close() method.
Your class explicitly contains an unmanaged resource - e.g. a COM object, pointers (yes, you can use pointers in managed C# but they must be declared in 'unsafe' blocks, etc.
In the case of unmanaged resources, you should also make sure to call System.Runtime.InteropServices.Marshal.ReleaseComObject() on the RCW. Even though the RCW is, in theory, a managed wrapper, there is still reference counting going on under the covers.
If your class subscribes to events using strong references. You need to unregister/detach yourself from the events. Always to make sure these are not null first before trying to unregister/detach them!.
Your class contains any combination of the above...
A recommended alternative to working with COM objects and having to use Marshal.ReleaseComObject() is to use the System.Runtime.InteropServices.SafeHandle class.
The BCL (Base Class Library Team) has a good blog post about it here http://blogs.msdn.com/bclteam/archive/2005/03/16/396900.aspx
One very important note to make is that if you are working with WCF and cleaning up resources, you should ALMOST ALWAYS avoid the 'using' block. There are plenty of blog posts out there and some on MSDN about why this is a bad idea. I have also posted about it here - Don't use 'using()' with a WCF proxy
Using lambdas instead of IDisposable.
I have never been thrilled with the whole using/IDisposable idea. The problem is that it requires the caller to:
know that they must use IDisposable
remember to use 'using'.
My new preferred method is to use a factory method and a lambda instead
Imagine I want to do something with a SqlConnection (something that should be wrapped in a using). Classically you would do
using (Var conn = Factory.MakeConnection())
{
conn.Query(....);
}
New way
Factory.DoWithConnection((conn)=>
{
conn.Query(...);
}
In the first case the caller could simply not use the using syntax. IN the second case the user has no choice. There is no method that creates a SqlConnection object, the caller must invoke DoWithConnection.
DoWithConnection looks like this
void DoWithConnection(Action<SqlConnection> action)
{
using (var conn = MakeConnection())
{
action(conn);
}
}
MakeConnection is now private
nobody answered the question about whether you should implement IDisposable even though you dont need it.
Short answer : No
Long answer:
This would allow a consumer of your class to use 'using'. The question I would ask is - why would they do it? Most devs will not use 'using' unless they know that they must - and how do they know. Either
its obviuos the them from experience (a socket class for example)
its documented
they are cautious and can see that the class implements IDisposable
So by implementing IDisposable you are telling devs (at least some) that this class wraps up something that must be released. They will use 'using' - but there are other cases where using is not possible (the scope of object is not local); and they will have to start worrying about the lifetime of the objects in those other cases - I would worry for sure. But this is not necessary
You implement Idisposable to enable them to use using, but they wont use using unless you tell them to.
So dont do it
Dispose pattern:
public abstract class DisposableObject : IDisposable
{
public bool Disposed { get; private set;}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~DisposableObject()
{
Dispose(false);
}
private void Dispose(bool disposing)
{
if (!Disposed)
{
if (disposing)
{
DisposeManagedResources();
}
DisposeUnmanagedResources();
Disposed = true;
}
}
protected virtual void DisposeManagedResources() { }
protected virtual void DisposeUnmanagedResources() { }
}
Example of inheritance:
public class A : DisposableObject
{
public Component components_a { get; set; }
private IntPtr handle_a;
protected override void DisposeManagedResources()
{
try
{
Console.WriteLine("A_DisposeManagedResources");
components_a.Dispose();
components_a = null;
}
finally
{
base.DisposeManagedResources();
}
}
protected override void DisposeUnmanagedResources()
{
try
{
Console.WriteLine("A_DisposeUnmanagedResources");
CloseHandle(handle_a);
handle_a = IntPtr.Zero;
}
finally
{
base.DisposeUnmanagedResources();
}
}
}
public class B : A
{
public Component components_b { get; set; }
private IntPtr handle_b;
protected override void DisposeManagedResources()
{
try
{
Console.WriteLine("B_DisposeManagedResources");
components_b.Dispose();
components_b = null;
}
finally
{
base.DisposeManagedResources();
}
}
protected override void DisposeUnmanagedResources()
{
try
{
Console.WriteLine("B_DisposeUnmanagedResources");
CloseHandle(handle_b);
handle_b = IntPtr.Zero;
}
finally
{
base.DisposeUnmanagedResources();
}
}
}
If you are using other managed objects that are using unmanaged resources, it is not your responsibility to ensure those are finalized. Your responsibility is to call Dispose on those objects when Dispose is called on your object, and it stops there.
If your class doesn't use any scarce resources, I fail to see why you would make your class implement IDisposable. You should only do so if you're:
Know you will have scarce resources in your objects soon, just not now (and I mean that as in "we're still developing, it will be here before we're done", not as in "I think we'll need this")
Using scarce resources
Yes, the code that uses your code must call the Dispose method of your object. And yes, the code that uses your object can use using as you've shown.
(2 again?) It is likely that the WebClient uses either unmanaged resources, or other managed resources that implement IDisposable. The exact reason, however, is not important. What is important is that it implements IDisposable, and so it falls on you to act upon that knowledge by disposing of the object when you're done with it, even if it turns out WebClient uses no other resources at all.
Some aspects of another answer are slightly incorrect for 2 reasons:
First,
using(NoGateway objNoGateway = new NoGateway())
actually is equivalent to:
try
{
NoGateway = new NoGateway();
}
finally
{
if(NoGateway != null)
{
NoGateway.Dispose();
}
}
This may sound ridiculous since the 'new' operator should never return 'null' unless you have an OutOfMemory exception. But consider the following cases:
1. You call a FactoryClass that returns an IDisposable resource or
2. If you have a type that may or may not inherit from IDisposable depending on its implementation - remember that I've seen the IDisposable pattern implemented incorrectly many times at many clients where developers just add a Dispose() method without inheriting from IDisposable (bad, bad, bad). You could also have the case of an IDisposable resource being returned from a property or method (again bad, bad, bad - don't 'give away your IDisposable resources)
using(IDisposable objNoGateway = new NoGateway() as IDisposable)
{
if (NoGateway != null)
{
...
If the 'as' operator returns null (or property or method returning the resource), and your code in the 'using' block protects against 'null', your code will not blow up when trying to call Dispose on a null object because of the 'built-in' null check.
The second reason your reply is not accurate is because of the following stmt:
A finalizer is called upon the GC destroying your object
First, Finalization (as well as GC itself) is non-deterministic. THe CLR determines when it will call a finalizer. i.e. the developer/code has no idea. If the IDisposable pattern is implemented correctly (as I've posted above) and GC.SuppressFinalize() has been called, the the Finalizer will NOT be called. This is one of the big reasons to properly implement the pattern correctly. Since there is only 1 Finalizer thread per managed process, regardless of the number of logical processors, you can easily degrade performance by backing up or even hanging the Finalizer thread by forgetting to call GC.SuppressFinalize().
I've posted a correct implementation of the Dispose Pattern on my blog: How to Properly Implement the Dispose Pattern
1) WebClient is a managed type, so you don't need a finalizer. The finalizer is needed in the case your users don't Dispose() of your NoGateway class and the native type (which is not collected by the GC) needs to be cleaned up after. In this case, if the user doesn't call Dispose(), the contained WebClient will be disposed by the GC right after the NoGateway does.
2) Indirectly yes, but you shouldn't have to worry about it. Your code is correct as stands and you cannot prevent your users from forgetting to Dispose() very easily.
Pattern from msdn
public class BaseResource: IDisposable
{
private IntPtr handle;
private Component Components;
private bool disposed = false;
public BaseResource()
{
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
Components.Dispose();
}
CloseHandle(handle);
handle = IntPtr.Zero;
}
disposed = true;
}
~BaseResource()
{ Dispose(false);
}
public void DoSomething()
{
if(this.disposed)
{
throw new ObjectDisposedException();
}
}
}
public class MyResourceWrapper: BaseResource
{
private ManagedResource addedManaged;
private NativeResource addedNative;
private bool disposed = false;
public MyResourceWrapper()
{
}
protected override void Dispose(bool disposing)
{
if(!this.disposed)
{
try
{
if(disposing)
{
addedManaged.Dispose();
}
CloseHandle(addedNative);
this.disposed = true;
}
finally
{
base.Dispose(disposing);
}
}
}
}
using(NoGateway objNoGateway = new NoGateway())
is equivalent to
try
{
NoGateway = new NoGateway();
}
finally
{
NoGateway.Dispose();
}
A finalizer is called upon the GC destroying your object. This can be at a totally different time than when you leave your method. The Dispose of IDisposable is called immediately after you leave the using block. Hence the pattern is usually to use using to free ressources immediately after you don't need them anymore.
From what I know, it's highly recommended NOT to use the Finalizer / Destructor:
public ~MyClass() {
//dont use this
}
Mostly, this is due to not knowing when or IF it will be called. The dispose method is much better, especially if you us using or dispose directly.
using is good. use it :)

Custom initialization functions with IDisposable

In .NET (C#) I follow some custom conventions and patterns that require Constructors, Initialization functions and IDisposable implementations. A typical class is illustrated below. No initialization is done directly in the constructor but rather through a dedicated function that is supposed to make the object reusable. However, I am not sure what happens when Dispose gets called. If the GC calls it, the reference to the object is lost anyways so no worries there. If it is explicitly called, are there any drawbacks simply calling Initialize and treating the class as a fresh object since GC.SupressFinalize has been called? Lol, I'm sure I could have asked this in an easier way.
public abstract class Thread: System.IDisposable
{
protected bool Disposed { get; set; }
protected bool Terminate { get; private set; }
public bool IsRunning { get; private set; }
private System.Threading.Thread ThreadObject { get; set; }
public Thread ()
{
this.Initialize();
}
~Thread ()
{
this.Dispose(false);
}
public virtual void Initialize ()
{
this.Stop();
this.Disposed = false;
this.Terminate = true;
this.IsRunning = false;
this.ThreadObject = null;
}
//====================================================================================================
// Functions: Thread
//====================================================================================================
public void Start ()
{
if (!this.IsRunning)
{
this.IsRunning = true;
this.Terminate = false;
this.ThreadObject = new System.Threading.Thread(new System.Threading.ThreadStart(this.Process));
this.ThreadObject.Start();
}
}
/// <summary>
/// Override this method to do thread processing.
/// [this.Terminate] will be set to indicate that Stop has been called.
/// </summary>
/// <param name="template"></param>
protected abstract void Process ();
public void Stop (System.TimeSpan timeout)
{
if (this.IsRunning)
{
this.Terminate = true;
try
{
if (timeout.TotalMilliseconds > 1D)
{
this.ThreadObject.Join(timeout);
}
else
{
this.ThreadObject.Join();
}
}
catch
{
try
{
this.ThreadObject.Abort();
}
catch
{
}
}
this.ThreadObject = null;
this.IsRunning = false;
}
}
//====================================================================================================
// Interface Implementation: System.IDisposable
//====================================================================================================
public void Dispose ()
{
this.Dispose(true);
System.GC.SuppressFinalize(this);
}
protected virtual void Dispose (bool disposing)
{
if (!this.Disposed)
{
if (disposing)
{
// Dispose managed resources.
this.Stop(System.TimeSpan.FromSeconds(1));
}
// Dispose unmanaged resources here.
// Note disposing has been done.
this.Disposed = true;
}
}
}
The GC never calls Dispose, it's up to the consuming code. The GC does however call the finalizer. This is used in the best practice IDisposable implementation to clean up unmanaged code only.
Where Dispose is used outside of the context of a finalizer, then there is no need for the GC to call the finalizer, and therefore SuppressFinalize is used as an optimisation to prevent it happening twice.
If the object is reused this causes an issue. Technically you can re-register the finalizer on initialization, but this would need to be made thread safe. Common practice is that an object is not reused after it has been Disposed, and typically the Dispose method should only execute exactly once. IMO the initializer method and object reuse introduces complexities to the pattern that move it away from it's intended purpose.
There's no technical reason why you can't reactivate a disposed object in this way, though I woudln't do it as it's against the principle of least surprise (most disposable objects are used once).
If you really do want to go this way, I'd avoid having a finalizer, which means your IDisposable class must not directly own any unmanaged resources. You can do this by wrapping any unmanaged resources your class uses in a manged wrapper (e.g. look at the SafeHandle class for an example).
I don't like all the precise details of your thread handling, but if you are going to have a class where each instance owns a thread, you should provide a Dispose method which will ensure that the instance's thread dies off in an orderly fashion.
If you want to allow for the thread to get cleaned up even when an object is abandoned, you'll probably have to create a wrapper object to which the outside application holds a reference but your thread does not. The Finalize() method for that wrapper object should nudge the thread in such a way that it will die off. The thread could simply poll a flag every few seconds to see if it should exit, or there could be a more sophisticated termination strategy.
I'm confused, though, why Initialize calls Stop()? I would have expected it to call Start().
Wrong language pattern appication sample is used in the code. I clearly see C++ backgroung for the C# code author. Unfortunately C++ coding techniques in not applicable in C# language.
Better not to allow object to get into garbage collector (GC), simply referencing it somewhere else, as in the Singleton pattern, rather that trying to resurrect disposed object, or use Dispose pattern in a language not allowing full control for the garbage collector and memory management, as is to be true, for example, in C++.
Simply, you should not use C++ idioms in C#, but the tips and tricks are:
Interfaces instead of pure virtual functions in C++,
Interface inheritancee instead of multiple class inheritance in C++,
No memory management (use weak references) instead of full controlled object lifetime in C++

Should Dispose() or Finalize() be used to delete temporary files?

I have a class that makes use of temporary files (Path.GetTempFileName()) while it is active. I want to make sure these files do not remain on the user's hard drive taking up space after my program is closed. Right now my class has a Close() method which checks if any temporary files used by the class still exist and deletes them.
Would it make more sense to put this code in the Dispose() or Finalize() methods instead?
Better yet would be to create the file with FileOptions.DeleteOnClose. This will ensure that the operating system forcibly deletes the file when your process exits (even in the case of a rude abort). Of course, you will still want to close/delete the file yourself when you are done with it, but this provides a nice backstop to ensure that you don't allow the files to be sit around forever
Example:
using (FileStream fs = File.Create(Path.GetTempFileName(), Int16.MaxValue,
FileOptions.DeleteOnClose))
{
// Use temp file
} // The file will be deleted here
I would do both; make the class disposable, and have the finalizer clean it up. There is a standard pattern for doing so safely and effectively: use it rather than attempting to deduce for yourself what the right pattern is. It is very easy to get wrong. Read this carefully:
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
Note that you've got to be really really careful when writing a finalizer. When the finalizer runs, many of your normal assumptions are wrong:
There are all kinds of potentials for race conditions or deadlocks because you are no longer on the main thread, you're on the finalizer thread.
In regular code, if you're running code inside an object then you know that all the things the object refers to are alive. In a finalizer, all the things the object refers to might have just been finalized! Finalizers of dead objects can run in any order, including "child" objects being finalized before "parent" objects.
In regular code, assigning a reference to an object to a static field could be perfectly sensible. In a finalizer, the reference you are assigning could be to an already dead object, and therefore the assignment brings a dead object back to life. (Because objects referred to by static fields are always alive.) That is an exceedingly weird state to be in and nothing pleasant happens if you do.
And so on. Be careful. You are expected to fully understand the operation of the garbage collector if you write a non-trivial finalizer.
A file is an unmanaged resource, and you implement IDisposable to clean up unmanaged resources that your classes are dependent upon.
I have implemented similar classes, although never in production code.
However, I understand your tentativeness about this - user interaction with the files outside of your application could screw things up and cause problems during disposal. However, that is the same for any file created/deleted by an application, regardless of whether or not it's tidied up by a Dispose() method or not.
I'd have to say that implementing IDisposable would be a reasonable choice.
A nice way is suggested by David M. Kean on the MSDN entry on Path.GetTempFileName. He creates a wrapper class implementing IDisposable that will automatically remove the file:
public class TemporaryFile : IDisposable
{
private bool _isDisposed;
public bool Keep { get; set; }
public string Path { get; private set; }
public TemporaryFile() : this(false)
{
}
public TemporaryFile(bool shortLived)
{
this.Path = CreateTemporaryFile(shortLived);
}
~TemporaryFile()
{
Dispose(false);
}
public void Dispose()
{
Dispose(false);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed)
{
_isDisposed = true;
if (!this.Keep)
{
TryDelete();
}
}
}
private void TryDelete()
{
try
{
File.Delete(this.Path);
}
catch (IOException)
{
}
catch (UnauthorizedAccessException)
{
}
}
public static string CreateTemporaryFile(bool shortLived)
{
string temporaryFile = System.IO.Path.GetTempFileName();
if (shortLived)
{
// Set the temporary attribute, meaning the file will live
// in memory and will not be written to disk
//
File.SetAttributes(temporaryFile,
File.GetAttributes(temporaryFile) | FileAttributes.Temporary);
}
return temporaryFile;
}
}
Using the new class is easy, just type the following:
using (TemporaryFile temporaryFile = new TemporaryFile())
{
// Use temporary file
}
If you decide, after constructing a TemporaryFile, that you want to prevent it from being deleted, simply set the TemporaryFile.Keep property to true:
using (TemporaryFile temporaryFile = new TemporaryFile())
{
temporaryFile.Keep = true;
}
Absolutely. This way you can ensure cleanup with exceptions present.
You should definitely use Dispose to clean up resources, but make sure you implement the IDisposable interface. You don't want to just add a method named Dispose.
I always make my classes that point to temp files IDisposable, and usually implement a finalizer that calls my dispose method there as well. This seems to be the paradigm suggested by the IDisposable MSDN page.
Related code below:
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
private void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
// Note disposing has been done.
disposed = true;
}
}
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~MyResource()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
If you wish to re-use your temporary files e.g. open\close\read\write\etc, then clearing them up at the AppDomain unload level can be useful.
This can be used in combination with putting temp files in a well known sub-directory of a temp location and making sure that the directory is deleted on application startup to ensure unclean shut-downs are taken care of.
A basic example of the technique (with exception handling removed around delete for brevity). I use this technique in file-based unit tests where it makes sense and is useful.
public static class TempFileManager
{
private static readonly List<FileInfo> TempFiles = new List<FileInfo>();
private static readonly object SyncObj = new object();
static TempFileManager()
{
AppDomain.CurrentDomain.DomainUnload += CurrentDomainDomainUnload;
}
private static void CurrentDomainDomainUnload(object sender, EventArgs e)
{
TempFiles.FindAll(file => File.Exists(file.FullName)).ForEach(file => file.Delete());
}
public static FileInfo CreateTempFile(bool autoDelete)
{
FileInfo tempFile = new FileInfo(Path.GetTempFileName());
if (autoDelete)
{
lock (SyncObj)
{
TempFiles.Add(tempFile);
}
}
return tempFile;
}
}

IDisposable

I am trying to adapt a class to work with just finished that I am not able to solve the problem.
My question is how to identify the handle to close / / CloseHandle (handle).
My problem is that I am not able to adapt the following code.
for (Int32 i = 0; i < temp_items.Count; i++)
{
string conj_itens = temp_itens[i].ToString();
ContarSuporte cs= new ContarSuporte(matriz_bin,strExpr);
_cont = cs.Suporte;
If (_cont>100)
{
list.add(conj_itens);
}
}
public class ContarSuporte: IDisposable
{
private int _cont;
private bool disposed = false;
private IntPtr handle;
public ContarSuporte()
{
}
public ContarSuporte(DataTable matriz_binaria, string strExpr)
{
int c = matriz_binaria.Rows.Count;
this._cont = (int)(matriz_binaria.Compute("COUNT(TID)", strExpr));
}
~ContarSuporte()
{
Dispose(false);
}
public void Dispose()
{
//GC.Collect();
Dispose(true);
GC.SuppressFinalize(this);
// GC.Collect();
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
//this.Dispose();
}
//CloseHandle(handle);
handle = IntPtr.Zero;
}
disposed = true;
}
public int Suporte
{
get
{
return _cont;
}
set
{
_cont =value;
}
}
You haven't shown any code actually using the handle. Are you really sure you need to implement IDisposable and have a handle in the first place? What unmanaged resource are you trying to use?
Were you perhaps just following a pattern that you saw elsewhere which did use a handle? You should only implement IDisposable when you actually need to - and implementing a finalizer should be very rare these days (as you can use SafeHandle instead of IntPtr for handles).
What handle are you trying to close? I can't see anything that allocates a handle.
Also - in many cases you can use SafeHandle to make this simpler - I can't tell whether this applies in your case, since I can't see what is going on...
the idea is to finish this instruction this._cont = (int)(matriz_binaria.Compute("COUNT(TID)", strExpr)); to each passage, the problem is not to increase the use of the memory I think most is because it is garbage.
my idea was to create a class to avoid the growth of memory. Already placed the _cont variable = 1 and had no impact on memory, and the problem that this raises intrucção memory, and the purpose and effect of each passage was interested in cleaning the garbage memory that is created with this instruction this._cont = (int)(matriz_binaria.Compute("COUNT(TID)", strExpr));**
Thanks

Categories