C# Examples

Menu:


Create an Asynchronous Method [C#]

This example shows how to create an asynchronous method conforming to the Event-based Asynchronous pattern.

This example is part of asynchronous method implementation series.

In this example, we create an asynchronous version of a method that processes a list of files.

[C#]
private void MyTask(string[] files)
{
  foreach (string file in files)
  {
    // a time consuming operation with a file (compression, encryption etc.)
    Thread.Sleep(1000);
  }
}

The asynchronous method implementation consists of the following members:

Notice how members names are derived from the original method name. This is the recommended way.

MyTaskWorker method

This method is executed on background and does the actual work of the original synchronous method. In this example, it doesn't differ from the original method. Notice that we also provide a delegate definition for this method.

[C#]
private void MyTaskWorker(string[] files)
{
  foreach (string file in files)
  {
    // a time consuming operation with a file (compression, encryption etc.)
    Thread.Sleep(1000);
  }
}

private delegate void MyTaskWorkerDelegate(string[] files);

IsBusy property

This property indicates a running asynchronous operation. Implementation of this property is needed, when concurrent invocations of asynchronous operations are not supported.

[C#]
private bool _myTaskIsRunning = false;

public bool IsBusy
{
  get { return _myTaskIsRunning; }
}

MyTaskAsync method

This method invokes the asynchronous operation and immediately returns. If an asynchronous operation is already running, an InvalidOperati­onException is thrown.

[C#]
public void MyTaskAsync(string[] files)
{
  MyTaskWorkerDelegate worker = new MyTaskWorkerDelegate(MyTaskWorker);
  AsyncCallback completedCallback = new AsyncCallback(MyTaskCompletedCallback);

  lock (_sync)
  {
    if (_myTaskIsRunning)
      throw new InvalidOperationException("The control is currently busy.");

    AsyncOperation async = AsyncOperationManager.CreateOperation(null);
    worker.BeginInvoke(files, completedCallback, async);
    _myTaskIsRunning = true;
  }
}

private readonly object _sync = new object();

First, an AsyncOperation is created. This object is used by the worker thread to invoke client's event handlers on the proper thread or context for the given application model.

Next, the asynchronous operation is started in a separate thread by the BeginInvoke method. Besides the files parameter, the BeginInvoke method has two additional parameters:

Be sure to throw no exceptions after the BeginInvoke statement.

MyTaskCompleted­Callback method

This method calls worker delegate's En­dInvoke method to finish the asynchronous operation and raises the MyTaskCompleted e­vent.

[C#]
private void MyTaskCompletedCallback(IAsyncResult ar)
{
  // get the original worker delegate and the AsyncOperation instance
  MyTaskWorkerDelegate worker =
    (MyTaskWorkerDelegate)((AsyncResult)ar).AsyncDelegate;
  AsyncOperation async = (AsyncOperation)ar.AsyncState;

  // finish the asynchronous operation
  worker.EndInvoke(ar);

  // clear the running task flag
  lock (_sync)
  {
    _myTaskIsRunning = false;
  }

  // raise the completed event
  AsyncCompletedEventArgs completedArgs = new AsyncCompletedEventArgs(null,
    false, null);
  async.PostOperationCompleted(
    delegate(object e) { OnMyTaskCompleted((AsyncCompletedEventArgs)e); },
    completedArgs);
}

First, the original worker delegate instance and the AsyncOperation object are obtained. Next, EndInvoke is called to free resources held by the asynchronous operation. At last, the MyTaskCompleted event is fired through the AsyncOperation object.

MyTaskCompleted event

This event is raised when the asynchronous operation is completed.

[C#]
public event AsyncCompletedEventHandler MyTaskCompleted;

protected virtual void OnMyTaskCompleted(AsyncCompletedEventArgs e)
{
  if (MyTaskCompleted != null)
    MyTaskCompleted(this, e);
}

In this series

  1. [C#] Create an Asynchronous Method – how to create an asynchronous method
  2. [C#] Asynchronous Method Progress Reporting – how to report progress
  3. [C#] Cancel an Asynchronous Method – implement cancellation support

See also

By Oto Skrkal, 24-May-2008