In Async/Await FAQ, Stephen Toub says:
An awaitable is any type that exposes a
GetAwaiter
method which returns a valid awaiter.
...
An awaiter is any type returned from an awaitable’sGetAwaiter
method and that conforms to a particular pattern.
So in order to be an awaiter, a type should:
INotifyCompletion
interface.IsCompleted
.GetResult
method that returns void
or TResult
.(I'm ignoring ICriticalNotifyCompletion
for now.)
I know the page I mentioned has a sample that shows how the compiler translates await operations but I'm stil having a hard time understanding.
When I await an awaitable,
IsCompleted
checked? Where should I set it?OnCompleted
called?OnCompleted
?OnCompleted
and using Task.Run(continuation)
in different examples, which should I go for and why?Why would you want a custom awaiter?
You can see the compiler's interpretation of await
here. Essentially:
var temp = e.GetAwaiter();
if (!temp.IsCompleted)
{
SAVE_STATE()
temp.OnCompleted(&cont);
return;
cont:
RESTORE_STATE()
}
var i = temp.GetResult();
Edit from comments: OnCompleted
should schedule its argument as a continuation of the asynchronous operation.
In the vast majority of cases, you as a developer need not worry about this. Use the async
and await
keywords and the compiler and runtime handle all this for you.
To answer your questions:
When does the code checks IsCompleted? Where should I set it?
The task should set IsCompleted
when the task has finished doing what it was doing. For example, if the task was loading data from a file, IsCompleted
should return true when the data is loaded and the caller can access it.
When does it calls OnCompleted?
OnCompleted usually contains a delegate supplied by the caller to execute when the task has completed.
Does it call OnCompleted in parallel or should the code inside OnCompleted be asynchronous?
The code in OnCompleted should be thread neutral (not care which thread it is called from). This may be problematic for updating COM objects in Single Threaded Apartments (like any UI classes in Metro/Windows8/Windows Store apps). It does not have to be asynchronous but may contain asynchronous code.
I saw examples of both directly invoking the continuation parameter of OnCompleted and using Task.Run(continuation) in different examples, which should I go for and when?
Use async
/await
when you can. Otherwise, use Task.Run() or Task.Wait() because they follow the sequential programming model most people are used to. Using continuations may still be required, particularly in Metro apps where you have apartment issues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With