Tag Archives: await

C# 5.0 Asynchronous Programming with async and await

The introduction of async and await in C# 5.0 makes asynchronous programming a breeze. In contrast with traditional asynchronous technique that is complicated. However, you need to understand how the new technique works and how to implement it properly.

First, lets see the code snippet below. A method that returns something.

        async Task<int> GetTotalCustomerAsync()
        {
            //the data to be returned
            int result = 0;
            using (SqlConnection conn = new SqlConnection("..."))
            {
                using (SqlCommand cmd = new SqlCommand("....", conn))
                {
                    //open the connection asynchronously
                    await conn.OpenAsync();
                    //execute the query
                    Object obj = await cmd.ExecuteScalarAsync();
                    //convert the result
                    if(obj!=null)
                    {
                        int.TryParse(obj.ToString(), out result);
                    }                    
                }
            }
            //return the result
            return result;
        }

Pointers:

  1. The method signature includes an async modifier
  2. The method must not return void. Except when you’re writing an async event handler.
  3. The method must return Task<TResult> or Task if it returns nothing.
  4. The method must have at least one await operator.
  5. By convention, the method ends with Async suffix. So that you will easily identify that the method is asynchronous and can be awaitable as you can see in the succeeding example.
  6. await can only be used to an asynchronous method provided by the type. e.g. SqlCommand.ExecuteNonQueryAsync(). Hence, you cannot await SqlCommand.ExecuteNonQuery();

Just follow the pointers and method signature above and you can implement an asynchronous programming technique easily. As stated in Pointers #4, there must be at least one await operator. The next question now is what if I have my own method but I can’t use the await operator inside because there is nothing asynchronous inside that I can call and I want that my method to be asynchronous? An example would be:

        double Compute()
        {
            double result = 0;
            //very extensive computation with I/O and it may take a while
            //the computed value is stored to result
            return result;
        }

        void MyMethod()
        {
            double finalResult = Compute();
        }

        //decorating with async and await like this
        //will not compile at all as noted in the pointers above
        //because Compute is not async and awaitable
        async Task MyMethod()
        {
            double finalResult = await Compute();
        }


TaskCompletionSource to the rescue. As defined by MSDN, “Represents the producer side of a Task unbound to a delegate, providing access to the consumer side through the Task property.” It is a little bit hard to understand but applying it in the example, I hope you can grasp the idea.

        Task<double> ComputeAsync()
        {
            double result = 0;

            //create a task completion source
            //the type of the result value should be the same
            //as the type in the returning Task            
            TaskCompletionSource<double> taskCompletionSource = new TaskCompletionSource<double>();

            //create and run the extenstive computation in background task
            //to complete taskCompletionSource.Task
            Task.Run(() =>
              {
                  try
                  {
                      //very extensive computation with I/O and it may take a while
                      //the computed value is stored to result
                      //....                      
                      //set the result to TaskCompletionSource
                      taskCompletionSource.SetResult(result);
                  }
                  catch (Exception ex)
                  {
                      //pass the exception to TaskCompletionSource
                      //for proper handling
                      taskCompletionSource.SetException(ex);
                  }
              }
            );
            //return the Task
            return taskCompletionSource.Task;
        }

Implementing an asynchronous programming is now easier than before. Likewise, you can make your own method to run asynchronously easily, too. However, it doesn’t mean that you have to convert all your methods to run asynchronously. In my own experience, I only convert those methods that require I/O and CPU extensive tasks that may complete for more than 50 milliseconds.

Advertisements