Saturday, February 14, 2015

Simplest async await C# example

Overview

  • Call the long running code from Task.Run()
  • Place await before Task.Run(). This pauses execution of the method calling Task.Run() and returns control to the method caller (the UI thread, for example). Once Task.Run() completes, execution of the method calling Task.Run() continues through. 
  • This is an ideal pattern for executing code from "click" and event handlers in a GUI application for a responsive user experience.
static void Main(string[] args)
{
// SomeMethodAsync executes code on a separate thread
Task<int> task = SomeMethodAsync();

// Control returns to Main() BEFORE 
//   execution of SomeMethodAsync() is completed
Console.WriteLine(
"4. Execution returns to Main()");

// Hold up the main thread until the asynchronous task 
//    is completed
// We do NOT need to do this from an event handler 
//    in a GUI application
Task.WaitAll(task);

// Print the result from MethodAsync()
Console.WriteLine("7. Task result is " + task.Result);
}


// Method is adorned with "async" to alert the compiler
//   that we will be using the "await" keyword
//   "async" adorned method must return Task or Task<>
static async Task<int> SomeMethodAsync()
{
int retval = 0;

try
{
Console.WriteLine("1. SomeMethodAsync() invoked");
// A "Task" runs code on a separate thread and is awaitable
//   Method waits for Task to complete because of "await"
// While the tasks runs, control is RETURNED back to Main()
Console.WriteLine("2. SomeMethodAsync() is waiting for Task to complete");
retval = await Task.Run(
() =>
{
Console.WriteLine("3. Task started");
int ret = LongRunningJob();
Console.WriteLine("5. Task completed");
return ret;
}
);
// Execution resumes in this method after Task is completed
Console.WriteLine("6. Execution resumes in SomeMethodAsync()");
}
// catch and finally behave the same way as you would normally expect
catch{} finally{}

return retval;
}

static int LongRunningJob()
{
Thread.Sleep(5000);
return 100;
}
}

Output

1. SomeMethodAsync() invoked
2. SomeMethodAsync() is waiting for Task to complete
3. Task started
4. Execution returns to Main()
5. Task completed
6. Execution resumes in SomeMethodAsync()
7. Task result is 100