【发布时间】:2015-11-16 08:31:15
【问题描述】:
假设我有一个同步运行的方法 fooCPU(它不调用执行 I/O 的纯异步方法,或使用其他线程通过调用 Task.Run 或类似方式运行其代码)。该方法执行一些繁重的计算 - 它受 CPU 限制。
现在我在我的程序中调用fooCPU 而不委托它由工作线程执行。如果fooCPU 的一行需要很长时间才能运行,那么在它完成之前不会执行其他行。例如,从 UI 线程调用它会导致 UI 线程冻结(GUI 将变得无响应)。
当我说 async/await 是对多线程的模仿时。两个不同的代码行在一个线程上轮流执行。如果其中一行需要很长时间才能运行,则在完成之前不会执行其他行。,
有人告诉我,在 UI 线程上使用异步是正确的,但对于所有其他情况(ASP.NET、线程池上的异步、控制台应用程序等)并非如此。
谁能告诉我这可能意味着什么? UI 线程与控制台程序的主线程有何不同?
我认为没有人希望这个论坛上的任何人继续讨论相关主题,例如它们出现在 cmets 中,所以最好提出一个新问题。
【问题讨论】:
-
我将在 win forms 应用程序和控制台应用程序上编译相同的代码,并使用 ildasm 或反射器检查编译后的 IL 的差异,以亲自查看。
-
@OguzOzgul 这对很多问题都很有用,但不是这个——代码完全相同。改变的是全局状态 - 同步上下文的存在。
-
答案非常好,但唯一能满足你好奇心的就是详细了解 await 的作用。搜索“.net await internals”看起来不错。如果你有一个小时的时间,我希望这能回答所有问题。
-
看看this in the threads section says 怎么说。我认为这是因为当在 UI 线程中创建异步任务时,用于回调 UI 线程的同步上下文总是通过调用this 来检索。我会尽快确认这一点。由于您的方法始终处于活动状态(没有非阻塞 io 操作),因此它在执行过程中使用 UI 线程。
-
看起来,UI 线程与控制台应用程序的主线程没有什么不同。一个 cpu 绑定的异步操作,在控制台主线程上使用 await 命令等待,仍然在同一个主线程上运行,并阻止控制台应用程序,就像它阻止(冻结)UI 一样。我认为这是一个误导性的评论,说在控制台应用程序或 Asp.Net 工作线程上的情况有所不同。由于您的 async 方法实际上没有执行任何异步操作,因此没有什么可等待的,并且执行永远不会返回到启动线程,与 Forms、Console 或 Web 应用程序无关
标签: c# multithreading async-await