.NET
Using IDisposable to restore temporary settings example
This is WinForms code from a long time ago, but the concept of using an IDisposable interface to do resource cleanup and restore a temporary setting is very valid.
You use the code below like this:
private void myMethod()
{
// set busy cursor
using (IDisposable waitCursor = new TemporaryCursor(this, System.Windows.Forms.Cursors.WaitCursor))
{
// logic that takes a long while
}
}
The code below implements the TemporaryCursor class; you can assign any System.Windows.Forms.Cursors item you want.
It restores the cursor upon these three “events”:
- The Dispose method either called directly on the class, or through the IDisposable.Dispose via for instance a using statement
- The ~TemporaryCursor desctructor syntax implementing the finalizer
- The HandleDestroyed event on the Control
Most often the IDispose pattern is being used to make sure that resources get cleaned up. If you think of a wait cursor as a temporary resource, this example becomes much easier to remember.
Of course this is not limited to the System.Windows.Forms realm, you can just as well use this for non-visual temporaries, and other kinds of UIs like ASP.NET, WPF or SilverLight.
using System.Windows.Forms;
namespace bo.Windows.Forms
{
public class TemporaryCursor : IDisposable
{
private Control targetControl;
private Cursor savedCursor;
private Cursor temporaryCursor;
private bool disposed = false;
public TemporaryCursor(Control targetControl, Cursor temporaryCursor)
{
if (null == targetControl)
throw new ArgumentNullException("targetControl");
if (null == temporaryCursor)
throw new ArgumentNullException("temporaryCursor");
this.targetControl = targetControl;
this.temporaryCursor = temporaryCursor;
savedCursor = targetControl.Cursor;
targetControl.Cursor = temporaryCursor;
targetControl.HandleDestroyed += new EventHandler(targetControl_HandleDestroyed);
}
void targetControl_HandleDestroyed(object sender, EventArgs e)
{
if (null != targetControl)
if (!targetControl.RecreatingHandle)
targetControl = null;
}
// public so you can call it on the class instance as well as through IDisposable
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (null != targetControl)
{
targetControl.HandleDestroyed -= new EventHandler(targetControl_HandleDestroyed);
if (temporaryCursor == targetControl.Cursor)
targetControl.Cursor = savedCursor;
targetControl = null;
}
disposed = true;
}
}
// Finalizer
~TemporaryCursor()
{
Dispose(false);
}
}
}
References: .NET/C#: Using IDisposable to restore temporary settrings example: TemporaryCursor class from our NCG partner Jeroen Pluimers at the The Wiert Corner blog.