Introduction
In this article, we’ll see how to write an asynchronous method. For better understanding, first we’ll perform a task conventionally and then we’ll create its async version.
Objective
To write an asynchronous method.
Background
Let us first design a class Task and write a Perform() method that iterates loops over some collection.
class Task
{
public void Perform(string[] files)
{
foreach (string file in files)
{
Thread.Sleep(100);
}
}
}
In the above example, we are iterating a loop for an array of strings. This is the conventional method which we all normally write. Now let’s try to perform the same task asynchronously using delegates. For this, we need the following members:
Perform() method – does actual work.
PerformAsync() method – invokes the asynchronous operation.
CompleteTask() method – called when perform method completed operation.
IsBusy property – indicates that an asynchronous operation is going on.
TaskCompleted event – notifies of the asynchronous operation completion.
Using the code
Perform() method:
This method executes in the background and does the actual task. In our example, it iterates a loop over an array of strings.
private void Perform(string[] files)
{
foreach (string file in files)
{
Thread.Sleep(100);
}
}
delegate void TaskEventHandler(string[] files,
AsyncOperation async, SendOrPostCallback callback);
PerformAsync() method:
This method invokes an asynchronous operation and returns immediately. If an asynchronous operation is running, then throw an exception.
public void PerformAsync(string[] files)
{
if (IsBusy)
throw new InvalidOperationException("The worker is busy.");
async = AsyncOperationManager.CreateOperation(this);
TaskEventHandler handler =
new TaskEventHandler(ProcessWorker);
handler.BeginInvoke(files, async, CompleteTask, null, null);
}
First it checks for busy status of operation, if it’s so, then throw InvalidCastOperationException. Next an AsyncOperation is created. This object is used by a worker thread to invoke the client’s event handler on a proper thread. Next TaskEventHandler is registered with a proper handler method. Through TaskEventHandler, we can invoke our Task asynchronously. Now the asynchronous operation is started in a separate thread using the handler.BeginInvoke method. The BeginInvoke method contains two more parameters along with a string array.
- A delegate of type
SendOrPostCallback to a callback method which is called when operation finishes.
- A custom object that is stored in the
AsyncState property of an IAsyncResult instance returned by the BeginInvoke method.
CompleteTask() method:
This method is called when a worker invoker has finished its processes.
void CompleteTask(object state)
{
object[] args = (object[])state;
RunWorkerCompletedEventArgs e =
args[0] as RunWorkerCompletedEventArgs;
AsyncOperation async = args[1] as AsyncOperation;
SendOrPostCallback callback = delegate(object darg)
{
OnRunWorkerCompleted(darg as RunWorkerCompletedEventArgs);
};
async.PostOperationCompleted(callback, e);
this.async = null;
}
First the AsyncOperation object is obtained and at last the TaskCompleted event is fired through the AsyncOperation object.
TaskCompleted Event:
This event is fired when the asynchronous operation completes.
public event RunWorkerCompletedEventHandler TaskCompleted
{
add
{
this.taskCompletedEventHandler += value;
}
remove
{
this.taskCompletedEventHandler -= value;
}
}
private RunWorkerCompletedEventHandler taskCompletedEventHandler;
protected virtual void OnTaskCompleted(RunWorkerCompletedEventArgs e)
{
if (taskCompletedEventHandler != null)
taskCompletedEventHandler(this, e);
}
In this Series
- [C#] Asynchronous method using C#: Part I
- [C#] Asychronous method using C#: Part II
I am Himanshu Manjarawala, Garduate in Computer Science and MCA From Veer Narmad South Gujarat University, Surat Gijarat India. Currently working as Sr. Software Developer in Automation Anywhere Softwares Pvt. Ltd. Vadodara, Gujarat