Monday, September 30, 2013

async/await Related

When the Main() method returns, the program usually ends, so the async keyword is not allowed to add before the Main entry.

The await keyword is placed in an async method. The async keyword indicates the method may contain async code. async Method can Return Task< TResult>, Task or void. By Lucian Wischik's blog(http://blogs.msdn.com/b/lucian/archive/2013/02/18/talk-the-new-async-design-patterns.aspx), Async void is a "fire-and-forget" mechanism: the caller is unable to know when an async void has finished, and the caller is unable to catch any exceptions from it. The only case where this kind of fire-and-forget is appropriate is in top-level event-handlers. Every other async method in your code should return "async Task". (or Task< TResult>)

For the eventhandlers called method, it can have async keyword: For example:

private async void Button1_Click(object sender, EventArgs args)
{
Textbox1.Text=await Task.Run(()=>SomeLongtimeWorktoGetText());
}

//notice for the async void Method, it is not able to do try/cath exception and as the return is void,
//it is not awaitable(e.g. Task has GetAwaiter() method) so it is not able to be used in other async/await block

In the Console application, we can do the samething writing async/await pattern:

class Program
{
static void Main(string[] args)
{

Task task=TestAsync();

//....

//notice if we want to synchronize the task we cannot use await task, and also the task is in the
//Status "Running", we cannot use Start() method to start it again.

task.Wait();

//...
}
}

public static async Task TestAsync()
{
Task t=Task.Run(()=>SomeLongtimeWork());

Console.WriteLine(await t);

}

public static int SomeLongtimeWork()
{
//...
return 1;
}


A bit more code added here:

class Program
{
static void Main(string[] args)
{

Task< int> task=TestAsync2(5);

//...
//notice that only the task is in a Status of "RantoCompletion" can we get the Result property,
// so the code to use task.Result will make our code synchronous as well,

Console.WriteLine(task.Result);
//...
}
}

public static async Task< int> TestAsync2(int i)
{
return await Task.Run(()=>SomeLongtimeWork2(i));

}

public static int SomeLongtimeWork2(int i)
{
//...
return i;
}