Lengthy Operation Windows Form Patterns


Introduction

"We are discussing design patterns everyday, however we don't know that we've already involved such kinds of patterns in our application".

In the following article we will introduce a series of patterns that would be used in Windows Forms applications. As I've said, maybe you've already used these patterns, but I still need to document these patterns in a formal manner.

Name

Lengthy Operation

Alias

Cursor Locking

Category

Idiom

Example

When developing Windows Forms applications, some UI operations may be considered "Lengthy Operations", which may lead users to wait for a long period of time while the system is processing. We should find a way that when the operation starts, the cursor is set to "Wait Cursor" and when the operation ends, the cursor is set back to default.

Context

Set cursor to wait when lengthy operation starts, and set it back when lengthy operation ends in Windows Forms applications.

Problem

It seems to be very easy to solve this problem. We simply need to set the status of the cursor when the operation starts and set it back when the operation ends. We can implement this by using the Cursor property on Forms; however, we cannot track the ending point of the lengthy operations. For example, if an exception is thrown or the function is returned in the operation, this may cause the operation to exit a variety of different ways. Code would become chaotic if we applied the Cursor property to every exit. Another problem is, we're not sure where and when the exception may be thrown and in such case we do not know where we should change back our cursors.

Solution

Use the "using" keyword to make a "scope" for our cursor handler. When entering the scope, change the cursor to "Wait Cursor" and when leaving the scope, change the cursor back.

Implementation

Defines a Lengthy Operation class and implements the IDisposable interface. Change the cursor to "Wait Cursor" in the constructor and change it back in "Dispose" method. Following is an example:

The LengthyOperation class:

internal class LengthyOperation : IDisposable

{

    private Form form__;

    public LengthyOperation(Form _form)

    {

        form__ = _form;

        form__.Cursor = Cursors.WaitCursor;

    }

    #region IDisposable Members

    public void Dispose()

    {

        form__.Cursor = Cursors.Default;

    }

    #endregion
}

The caller class:

using (new LengthyOperation (this))

{

     // Lengthy operation goes here
}

Known Uses
SunnyCrystal Business Platform
SunnyCrystal Distributed Filesystem

References

Scoped Locking Pattern [POSA2]