Pages

venerdì 16 novembre 2012

Asynchronous code for dummies with async and await

From the latest versions of .NET framework Microsoft started to take care more about responsive interfaces that doesn't block while a long task is executed in background. This is made by writing the code in an asynchronous way letting two or more functions execute in parallel.

choosing images is my favourite thing to do in this blog.

the big problem of writing asynchronous code is that is more fiddly to write and less clear to read than a syncronous one. Microsoft is famous for let coding accessible even for monkeys: for this reason in the brand new framework 4.5 they included the modificator "async" and the operator "await".

It works like this: initially we write a function that we need to be asynchronous and add the "async" modificator

async Task<int> bullshitAsync()
{
LongAndTediousJob();
return 1;
}

this function needs to:

declare Task, Task<T> or void as return value.

obviously, the async modificator.

in case the return value is declared as Task<T>, return a value of type T.

(This is optional) add "Async" at the name of the function.

After that, to execute that function in asynchronous way we just need to use the await operator as follows

//in case we have Task<T> as return value
//and we need the result of the function
int result = await bullshitAsync();
//in case we have Task or void as return value
//or simply we don't give a shit about the result
await bullshitAsync();

In this case the program will wait until the end of the execution of the function WITHOUT BLOCKING THE INTERFACE. this procedure hides to the programmer the fact that the code is executed in a different thread.

That's not all...we have just seen how to avoid to block the interface, but we don't know yet how to execute code in parallel. To achieve this we need to call the function in an alternative way.

//taskBullshitAsync is an instance of class Task<int>
//that we'll need when we'll have to wait
//the end of the function bullshitAsync
Task<int> taskBullshitAsync = bullshitAsync();
//this piece of code will be executed
//in parallel with bullshitAsync()
bullshitParallel();
//now we need the result, so we use
//the Task object with the await operator
//to wait the result of bullshitAsync()
int result = await taskBullshitAsync;

In this case the execution of bullshitAsync starts when the function is called, but the rest of the function is executed without waiting the result. the Task<int> object obtained in the first line will be used in addition to the await operator when we need the return value.

As you can see, the implementation is very easy but never forget that asynchronous programming have ITS OWN COMPLEXITY, we have to deal with data concurrency and possible scenarios of deadlocks or starvation...in this case monkey can't do too much.

Not to mention, this feature is available just from framework 4.5, so i do not recommend to use it if you want to develop something that aims to be available for previous versions of .NET.