Using scope in C#

Microsoft managed code uses the garbage collector to reclaim space when objects go out of scope. This is a great advantage in that it frees the programmer from worrying about releasing resources. The programmer can’t predict when garbage collection will occur though. Unfortunately that also prevents you from using scope to your advantage. You can’t just put code in the destructor and assume it will be called when the object goes out of scope. If you created a mutex object (like I did in a previous post about C++ scoping) and left the unlock in the destructor you’d have no way to guarantee when your mutex would get unlocked.

There’s a handy trick to get around that problem. You can use scoping to your advantage if you combine the “using” keyword and the IDisposable interface. The IDisposable interface adds a Dispose() method to your class. The using keyword guarantees to call the Dispose method of any objects that are created using the keyword. The combination of the two of them does what the C++ scoping does.

Here’s an example of a class that is useful for winforms programmers. If you’re doing a rigorous job you know you should change the cursor to provide a visual indicatation the computer is working on a task. It’s a pain to ensure that the cursor is always set back to it’s original state when you finish the task. If an exception occurs you can end up with the user thinking the machine is still working on the task when it’s not.

public class BusyCursor : IDisposable
{
private Cursor _PreviousCursor;
private Form _ParentForm;

/// <summary>
/// Constructor
/// Saves form’s current cursor
/// Changes the cursor to a busy cursor
/// </summary>
/// <param name="ParentForm"></param>
public BusyCursor( Form ParentForm )
{
_ParentForm = ParentForm;
_PreviousCursor = _ParentForm.Cursor;
_ParentForm.Cursor = Cursors.WaitCursor;
}

#region IDisposable Members

public void Dispose()
{
_ParentForm.Cursor = _PreviousCursor;
}

#endregion
}

This class saves the cursor currently used by the form you pass to it. It then changes the cursor to the busy cursor. When it goes out of scope it restores the cursor to the original state.

You use the class like this:

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void  button1_Click(object sender, EventArgs e)
{
using ( BusyCursor ShowBusyCursor = new BusyCursor(this) )
{
// long running process here
System.Threading.Thread.Sleep( 10000 );
}
}
}

It’s simple to implement, works very well, and isn’t terribly hard to understand.

Another day in the life of a workaday programmer batman.

++djs

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: