Question about .Net Tasks and the Async CTP
I'm experimenting with the Async CTP and liking it quite a bit. I did have a question from the whitepaper explaining it however. In it, it says:
It is important to understand that async methods li开发者_Python百科ke (an example method listed in the whitepaper) do not run on their own thread.
If they don't run on their own thread, how does the asynchronous behavior work? Is there a lot of context switching on the existing thread between (say) the UI and the Task that the "await" keyword creates?
When you call an async method, it's initially synchronous. It doesn't even have the chance of being asynchronous until it hits an await.
At each await expression, GetAwaiter()
is called on the awaitable that you're awaiting. Then the IsCompleted
property is tested on the awaiter. If the task has already completed, the method keeps going synchronously.
Otherwise, the OnCompleted
method is called on the awaiter, to add a continuation to it, which is then called back when the task has finished. The async method itself returns to the caller the first time it hits an await expression which isn't already completed.
The exact nature of the threading of this depends on the awaiter involved, but in the async CTP for Task<T>
, the TaskAwaiter
will use the current task scheduler to schedule the continuation. For WinForms/Silverlight/WPF, that means if you start an async method on the UI thread, it continues on the UI thread. Otherwise (e.g. if you're already on a thread-pool thread, or you're using this from a console app) the continuation will run on a thread-pool thread. Of course, you can change the current task scheduler yourself if you really want.
Likewise different awaiters don't have to schedule continuations using TaskScheduler.Current
. For example, my coroutine continuations basically keep a queue of continuations to execute, and keep going until they're going. My ComeFrom continuations end up being even more bizarre :)
For more on how the async feature works under the hood, read my Eduasync blog series which delves into it fairly deeply.
Hope you're enjoying the feature in general though... I think it's tremendously exciting.
The idea behind an async method is that it doesn't require a thread to run, it merely makes the invocation and joining of the completion of an asynchronous operation flow in a linear manner. I.e. if you use an async method to read from a file, it synchronously calls the begin part of the file read and is then suspended from execution (i.e. relinquishes the current thread to do other operations) until the OS level operation completes and call the completion provided, which unsuspends the remainder of your async method (at least until the next await).
精彩评论