The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Email Subscription

    Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 716 other subscribers

.NET/C#: Using IDisposable to restore temporary settrings example: TemporaryCursor class

Posted by jpluimers on 2012/01/26

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:

[sourcecode language=”csharp”]
private void myMethod()
{
// set busy cursor
using (IDisposable waitCursor = new TemporaryCursor(this, System.Windows.Forms.Cursors.WaitCursor))
{
// logic that takes a long while
}
}
[/sourcecode]

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”:

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.

[sourcecode language=”csharp”]
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);
}
}
}
[/sourcecode]

–jeroen

4 Responses to “.NET/C#: Using IDisposable to restore temporary settrings example: TemporaryCursor class”

  1. […] A long while ago, I wrote about a (then overdue post) on .NET/C#: Using IDisposable to restore temporary settrings example: TemporaryCursor class. […]

  2. […] 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. […]

  3. Ramon's avatar

    Ramon said

    Moet in de Dispose method de parameter disposing niet gecheckt worden en moet de check if (temporaryCursor == targetControl.Cursor)
    niet (temporaryCursor != targetControl.Cursor) zijn?

    • jpluimers's avatar

      jpluimers said

      Lets keep this in English :)
      “Should inside the Dispose method:

      1. the parameter disposing be checked
      2. the check if (temporaryCursor == targetControl.Cursor) be (temporaryCursor != targetControl.Cursor)

      ?”
      Answer:

      1. yes, and no. That normally is the correct IDisposabla pattern implementation for unmanaged resources (http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx). I will correct this shortly to implement the disposed. No, even though this is a managed resource, you need to always restore it, be it through a using/IDisposable usage, or through the finalizer (when someone calls it without using/IDisposable).
      2. no, as in the example both temporaryCursor is Cursors.WaitCursor and targetControlCursor should only be restored if it indeed still has that value.

      –jeroen

Leave a Comment

 

Discover more from The Wiert Corner - irregular stream of stuff

Subscribe now to keep reading and get access to the full archive.

Continue reading