问题描述
我一直在考虑在C#5新的异步的东西,一个特定的问题出现了。
I've been considering the new async stuff in C# 5, and one particular question came up.
据我所知,的await
关键字是实施的时,其中所述方法的其余部分被分成任务
对象和排队行动才能运行,但是,其中的控制是返回到调用方法。
I understand that the await
keyword is a neat compiler trick/syntactic sugar to implement continuation passing, where the remainder of the method is broken up into Task
objects and queued-up to be run in order, but where control is returned to the calling method.
我的问题是,我听说现在这是所有在单个线程。这是否意味着这个异步的东西真的只是一个转弯延续code到工作
对象,然后调用 Application.DoEvents方式()
启动下一个之前每个任务完成后?
My problem is that I've heard that currently this is all on a single thread. Does this mean that this async stuff is really just a way of turning continuation code into Task
objects and then calling Application.DoEvents()
after each task completes before starting the next one?
还是我失去了一些东西? (问题的这部分是修辞 - 我完全知道我缺少的的东西的:))
Or am I missing something? (This part of the question is rhetorical - I'm fully aware I'm missing something :) )
提前非常感谢。
推荐答案
是同时的,在这个意义上,许多优秀的异步操作可能会在任何时间进度。它可能是也可能不是多线程的
It is concurrent, in the sense that many outstanding asychronous operations may be in progress at any time. It may or may not be multithreaded.
在默认情况下,等待
将安排继续回到当前执行上下文。 当前执行上下文被定义为 SynchronizationContext.Current
,如果它是非 - 空
或 TaskScheduler.Current
如果没有的SynchronizationContext
。
By default, await
will schedule the continuation back to the "current execution context". The "current execution context" is defined as SynchronizationContext.Current
if it is non-null
, or TaskScheduler.Current
if there's no SynchronizationContext
.
您可以通过调用覆盖此默认行为 ConfigureAwait
并通过假
为 continueOnCapturedContext
参数。在这种情况下,继续将不被排定回该执行上下文。这通常意味着它会在一个线程池的线程中运行。
You can override this default behavior by calling ConfigureAwait
and passing false
for the continueOnCapturedContext
parameter. In that case, the continuation will not be scheduled back to that execution context. This usually means it will be run on a threadpool thread.
除非你正在编写库code,默认行为正是所需要的。的WinForms,WPF和Silverlight(即,所有的UI框架)提供一个的SynchronizationContext
,那么继续在UI线程上执行(和可以安全地访问UI对象)。 ASP.NET还提供了一个的SynchronizationContext
,以确保继续在正确的请求上下文中执行。
Unless you're writing library code, the default behavior is exactly what's desired. WinForms, WPF, and Silverlight (i.e., all the UI frameworks) supply a SynchronizationContext
, so the continuation executes on the UI thread (and can safely access UI objects). ASP.NET also supplies a SynchronizationContext
that ensures the continuation executes in the correct request context.
其他线程(包括线程池线程,发
和的BackgroundWorker
)不提供的SynchronizationContext
。因此,控制台应用程序和Win32服务在默认情况下不具有的SynchronizationContext
可言。在这种情况下,延续上执行线程池线程。这就是为什么控制台应用程序演示使用伺机
/ 异步
包括到Console.ReadLine /
ReadKey
或做阻塞等待
在任务
。
Other threads (including threadpool threads, Thread
, and BackgroundWorker
) do not supply a SynchronizationContext
. So Console apps and Win32 services by default do not have a SynchronizationContext
at all. In this situation, continuations execute on threadpool threads. This is why Console app demos using await
/async
include a call to Console.ReadLine
/ReadKey
or do a blocking Wait
on a Task
.
如果你发现自己需要一个的SynchronizationContext
,你可以使用的库 ;它基本上只是提供了一个异步
兼容主循环用的SynchronizationContext
。我觉得它有用的控制台应用程序(VS2012目前已经内置支持异步任务
单元测试)。
If you find yourself needing a SynchronizationContext
, you can use AsyncContext
from my Nito.AsyncEx library; it basically just provides an async
-compatible "main loop" with a SynchronizationContext
. I find it useful for Console apps (VS2012 now has built-in support for async Task
unit tests).
有关的SynchronizationContext
了解更多信息,请参见。
For more information about SynchronizationContext
, see my Feb MSDN article.
在任何时候为的DoEvents
或称为同等学历;相反,控制流的返回的所有的方式,并延续(函数的其余部分)将于稍后运行。这是一个更清洁的解决方案,因为它不会导致重新进入的问题,如你会如果的DoEvents
使用了。
At no time is DoEvents
or an equivalent called; rather, control flow returns all the way out, and the continuation (the rest of the function) is scheduled to be run later. This is a much cleaner solution because it doesn't cause reentrancy issues like you would have if DoEvents
was used.
这篇关于C#5异步/等待 - 是*并发*?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!