Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is resumption from await implemented?

I've been reading Eric Lippert's blog posts on Asynchrony in C# 5 (part 4 being particular relevant) and have watched Anders PDC10 talk on the subject and I'm unclear on how continuations from asynchronous methods are resumed in a single threaded context.

Both sources discuss using asynchronous methods in a single threaded UI loop to improve responsiveness and in Anders' example he mentions that when an asynchronous task completes it's continuation is scheduled by the addition of a message to the message pump.

Does the asynchronous method really know that it needs to perform what seems like a context specific action, or was this a simplification?

More generally, how can resumption from asynchronous methods handled in a single threaded context? Is there a requirement for scheduling within a single thread?

like image 703
Simon Walker Avatar asked Mar 21 '11 12:03

Simon Walker


People also ask

How is await implemented?

JavaScript Async Functions Async and await are built on promises. The keyword “async” accompanies the function, indicating that it returns a promise. Within this function, the await keyword is applied to the promise being returned. The await keyword ensures that the function waits for the promise to resolve.

How does the await keyword work in C#?

The await operator suspends evaluation of the enclosing async method until the asynchronous operation represented by its operand completes. When the asynchronous operation completes, the await operator returns the result of the operation, if any.

Does await make it synchronous?

Async/await helps you write synchronous-looking JavaScript code that works asynchronously. Await is in an async function to ensure that all promises that are returned in the function are synchronized. With async/await, there's no use of callbacks.

What does await actually do?

The await expression causes async function execution to pause until a promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfillment.


1 Answers

The task continuation knows where the continuation needs to be scheduled - e.g. "any thread pool thread" or "the UI thread".

This behaviour is determined by the "awaiter", however - it's not actually part of what the C# compiler is responsible for. The compiler just calls BeginAwait and passes in the continuation; the awaiter returns a Boolean value indicating whether the task has already completed synchronously, or whether the caller should return and let the continuation occur asynchronously.

So for the moment, that decision is made in the awaiter returned by TaskEx - but I wouldn't be surprised to see it all get bundled into Task eventually. That can flow things like the synchronization context, which knows how further actions should be handled.

I'm not quite sure what sort of genuinely single-threaded context you're considering... or are you thinking of a situation where the bulk of the work needs to happen in a single thread, but other threads can be involved for the asynchronous bit (e.g. when an HTTP packet is received, processed on an IO completion port thread, and the response handled back on the UI thread)?

like image 116
Jon Skeet Avatar answered Sep 28 '22 00:09

Jon Skeet