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.