Runtime evaluation of await expressions
At runtime, the expression await t is evaluated as follows: · An awaiter a is obtained by evaluating the expression (t).GetAwaiter(). · A bool b is obtained by evaluating the expression (a).IsCompleted. · If b is false then evaluation depends on whether a implements the interface System.Runtime.CompilerServices.ICriticalNotifyCompletion (hereafter known as ICriticalNotifyCompletion for brevity). This check is done at binding time; i.e. at runtime if a has the compile time type dynamic, and at compile time otherwise. Let r denote the resumption delegate (§10.14): o If a does not implement ICriticalNotifyCompletion, then the expression o If a does implement ICriticalNotifyCompletion, then the expression o Evaluation is then suspended, and control is returned to the current caller of the async function. · Either immediately after (if b was true), or upon later invocation of the resumption delegate (if b was false), the expression (a).GetResult() is evaluated. If it returns a value, that value is the result of the await-expression. Otherwise the result is nothing. An awaiter’s implementation of the interface methods INotifyCompletion.OnCompleted and ICriticalNotifyCompletion.UnsafeOnCompleted should cause the delegate r to be invoked at most once. Otherwise, the behavior of the enclosing async function is undefined.
|