Den*_*iev 3 .net c# asynchronous task-parallel-library async-await
当可等待任务完成但启动异步方法的线程不可用(例如处理另一个请求)时,在 C# 中会发生什么?然后将使用另一个线程而不是第一个线程,或者执行将等到繁忙线程可用?
预先感谢您的回答。
这取决于SynchronizationContext安排延续的线程的 。
例如,当您在async/await具有 UI 线程的应用程序(如 ASP.NET 或 WPF 应用程序)中使用时,在 UI 线程上安排的任何延续也将在 UI 线程上执行。在控制台应用程序中,没有SynchronizationContext被捕获,并且默认行为是在必须恢复执行时在任何可用线程上执行。如果您考虑一下,实际上在“任何”线程上执行比在安排延续的完全相同的线程上执行要容易得多。
所有这些都只是部分正确,因为您可以通过在ing之前调用返回来配置await调用以不捕获当前。SynchronizationContextConfigureAwait(false)Taskawait
为了说明这一点,请注意,如果在 ASP.NET 应用程序中,您在 UI 线程上启动异步工作,然后强制它阻塞直到该工作完成,则您的代码可能会死锁,例如通过调用Task.Result返回的Task. 现在您有一个必须在 UI 线程上执行的延续,但 UI 线程正在等待该延续的执行,因此不会继续执行。如果您在控制台应用程序中执行相同操作并且线程池中有空闲线程,则代码不会阻塞,因为它可以在“任何”线程上自由执行。调用后在任何应用程序中都会发生同样的情况ConfigureAwait(false)- 因为不会SynchronizationContext被捕获。
TL;DR:您实际上问了一个相当简单的问题,但答案却非常复杂。简而言之:允许在任何线程上继续执行,除非SynchronizationContext强制执行其他操作。进入更多细节会将这个答案变成一篇相当大的博客文章,比我聪明得多的人已经制作了关于此的博客文章,所以我只会将您链接到有关该主题的更多资源:
Stephen Toub 的常见问题解答 ConfigureAwait
Stephen Toub 的“Await、SynchronizationContext 和控制台应用程序”
Stephen Cleary 关于 ASP.NET Core SynchronizationContext
为什么控制台应用程序中未捕获默认 SynchronizationContext?
| 归档时间: |
|
| 查看次数: |
302 次 |
| 最近记录: |