C# Async

Async is a new keyword added in C# 5.0 which is a key part of the asynchronous programming model. In C#, Async is modifier which is added to a method which denotes that the method contains control flow which involves waiting for asynchronous operations and will therefore be rewritten by the compiler to ensure that the asynchronous operations can resume this method at the correct point.
The focus of async methods is to ensure that you stay on the current thread as much as possible. Async methods therefore bring single-threaded cooperative multitasking to C#.

Note the Async keyword does not mean the method will automatically run asynchronously on a worker thread, it actually means the opposite – the method will run on the current thread as much as possible but contains code which may run asynchronously at various points.

Lets look at a simple example, the below code is standard C# code for a method named SaveDocuments which also calls a function Save for save each document

void SaveDocuments(List urls)
{
  for(int i = 0; i < urls.Count; ++i)
    Save(Fetch(urls[i]));
}

Using the new asynchronous programming model in C# 5.0, this method could have the async keyword added to facilitate the method operating asynchronously:

async void SaveDocuments(List urls)
{
  Task save = null;
  for(int i = 0; i < urls.Count; ++i)
  {
    var document = await FetchAsync(urls[i]);
    if (save != null)
      await save;
    save = SaveAsync(document);
  }
}

The above code assumes a simple implementation of both the FetchAsync and SaveAsync methods. Note also the use of the await operator which is used twice in that method. The await operator means if the task we are awaiting has not yet completed then sign up the remainder of the method as the continuation of that task, and then immediately return to your caller and the task will then invoke the continuation when it completes.

In this model, an asynchronous method typically returns a Task let’s assume for now that FetchAsync returns a Task. In this code the call to FetchAsync creates and then returns a Task<Document> - (ie an object representing “hot” running task). Calling this method immediately will return a Task<Document> that asynchronously fetches the required document. The exact method by which is does this is not know to use – it may run on another thread, or posts itself to a Windows message queue on the current thread that some message loop is polling for info on work needing to be performed in idle time. All we know is that we need something to happen upon it completing.

So why use Task in the above code? The point is that asynchrony doesn’t require parallelism, however parallelism require asynchrony, and most of the tools useful for parallelism can also be easily used for non-parallel asynchrony. Thus, there isn’t any inherent parallelism in Task; for the Task Parallel Library to use a task-based pattern to represent units of pending work which can then be parallelized doesn’t require multithreading.

Twitter Digg Delicious Stumbleupon Technorati Facebook Email
Uncategorized

No comments yet... Be the first to leave a reply!