Await
keyword is used with awaitable types (.NET comes with existing two such types, Task
and Task<T>
). However, it's possible to write your own awaitable type.
The msdn blog post states that:
you can think of the following code:
await FooAsync(); RestOfMethod();
as being similar in nature to this:
var t = FooAsync(); var currentContext = SynchronizationContext.Current; t.ContinueWith(delegate { if (currentContext == null) RestOfMethod(); else currentContext.Post(delegate { RestOfMethod(); }, null); }, TaskScheduler.Current);
Does the (pseudo)code above follow from the implementation of awaitable type (such as Task
), or maybe is it just the way the compiler deals with any awaitable type that is on the right of the await
keyword?
In the comments section below, there's a post explaining the difference between TaskScheduler and SynchronizationContext.
The primary difference is that SynchronizationContext is a general mechanism for working with delegates, whereas TaskScheduler is specific to and catered to Tasks (you can get a TaskScheduler that wraps a SynchronizationContext using TaskScheduler.FromCurrentSynchronizationContext). This is why awaiting Tasks takes both into account, first checking a SynchronizationContext (as the more general mechanism that most UI frameworks support), and then falling back to a TaskScheduler. Awaiting a different kind of object might choose to first use a SynchronizationContext, and then fall back to some other mechanism specific to that particular type.
If I understand the last sentence correctly, it means I can put any delegate I want in the continueWith
method (I mean the t.ContinueWith
call in code sample above), i.e. modify how await
works when used with my custom awaitable object.
Just in case you want to know more: http://blogs.msdn.com/b/pfxteam/archive/2009/09/22/9898090.aspx