jjzjj

c# - 异步/等待 - 是*并发*吗?

coder 2023-07-08 原文

我一直在考虑 C# 5 中的新异步内容,并提出了一个特定问题。

我知道 await 关键字是一个巧妙的编译器技巧/语法糖来实现 continuation passing ,方法的其余部分被分解为 Task 对象并排队按顺序运行,但控制权返回给调用方法。

我的问题是我听说目前这一切都在一个线程上。这是否意味着这种异步的东西真的只是一种将延续代码转换为 Task 对象然后在每个任务完成后调用 Application.DoEvents() 开始下一个任务的方法?

还是我遗漏了什么? (问题的这一部分是修辞性的 - 我完全知道我错过了一些东西 :))

最佳答案

它是并发的,从某种意义上说,许多未完成的异步操作可能随时在进行中。它可能是也可能不是多线程

默认情况下,await 会将继续安排回“当前执行上下文”。 “当前执行上下文”定义为 SynchronizationContext.Current 如果它是非 null,或者 TaskScheduler.Current 如果没有 同步上下文

您可以通过调用 ConfigureAwait 并为 continueOnCapturedContext 参数传递 false 来覆盖此默认行为。在这种情况下,延续将不会被安排回该执行上下文。这通常意味着它将在线程池线程上运行。

除非您正在编写库代码,否则默认行为正是您所需要的。 WinForms、WPF 和 Silverlight(即所有 UI 框架)提供一个 SynchronizationContext,因此延续在 UI 线程上执行(并且可以安全地访问 UI 对象)。 ASP.NET 还提供了一个 SynchronizationContext 来确保继续在正确的请求上下文中执行。

其他线程(包括线程池线程、ThreadBackgroundWorker)不提供SynchronizationContext。因此控制台应用程序和 Win32 服务在默认情况下根本没有 SynchronizationContext。在这种情况下,延续在线程池线程上执行。这就是为什么使用 await/async 的控制台应用程序演示包括对 Console.ReadLine/ReadKey 的调用或执行在 Task 上阻塞 Wait

如果您发现自己需要一个SynchronizationContext,您可以使用AsyncContext来 self 的 Nito.AsyncEx图书馆;它基本上只是提供了一个与 SynchronizationContext 兼容的 async 的“主循环”。我发现它对控制台应用和单元测试很有用(VS2012 现在内置了对async Task 单元测试的支持)。

有关SynchronizationContext 的更多信息,请参阅my Feb MSDN article .

在任何时候都不会调用 DoEvents 或等效项;相反,控制流一直返回,并且后续(函数的其余部分)计划稍后运行。这是一个更简洁的解决方案,因为它不会像使用 DoEvents 时那样导致重入问题。

关于c# - 异步/等待 - 是*并发*吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7663101/

有关c# - 异步/等待 - 是*并发*吗?的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  4. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  5. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  6. ruby-on-rails - 获取并发布相同匹配项的请求 - 2

    在我的路线文件中我有:match'graphs/(:id(/:action))'=>'graphs#(:action)'如果是GET请求(工作)或POST请求(不工作),我想匹配它我知道我可以使用以下方法在资源中声明POST请求:post'/'=>:show,:on=>:member但是我怎样才能为比赛做到这一点呢?谢谢。 最佳答案 如果你同时想要POST和GETmatch'graphs/(:id(/:action))'=>'graphs#(:action)',:via=>[:get,:post]编辑默认值可以设置如下match'g

  7. c# - C# 中的 Flatten Ruby 方法 - 2

    我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume

  8. ruby - 可以像在 C# 中使用#region 一样在 Ruby 中使用 begin/end 吗? - 2

    我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用

  9. c# - Ruby 等效于 C# Linq 聚合方法 - 2

    什么是Linq聚合方法的ruby​​等价物。它的工作原理是这样的varfactorial=new[]{1,2,3,4,5}.Aggregate((acc,i)=>acc*i);每次将数组序列中的值传递给lambda时,变量acc都会累积。 最佳答案 这在数学以及几乎所有编程语言中通常称为折叠。它是更普遍的变形概念的一个实例。Ruby从Smalltalk中继承了这个特性的名称,它被称为inject:into:(像aCollectioninject:aStartValueinto:aBlock一样使用。)所以,在Ruby中,它称为inj

  10. ruby - Watir ... sleep 和等待之间的区别 - 2

    有什么显着的区别吗sleep10和wait_until(10)他们似乎都在做同样的事情:WAITING10秒,然后继续下一步 最佳答案 sleep在指定时间内什么都不做。wait_untiltakesablock.它一直等到block评估为真或超时。如果没有给出block,它们的行为相同。 关于ruby-Watir...sleep和等待之间的区别,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/que

随机推荐