C#5异步/等待 - 是*并发*? [英] C# 5 Async/Await - is it *concurrent*?

查看:175
本文介绍了C#5异步/等待 - 是*并发*?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在考虑在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 <通话/ code> / 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 ,你可以使用的 AsyncContext 从我的 Nito.AsyncEx 库 ;它基本上只是提供了一个异步兼容主循环用的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 and unit tests (VS2012 now has built-in support for async Task unit tests).

有关的SynchronizationContext 了解更多信息,请参见我二月MSDN文章

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异步/等待 - 是*并发*?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆