c# - 何时使用 Task.Run().GetAwaiter().GetResult() 和 ().GetAwaiter.GetResult()?
问题描述
我有一个需要同步调用的异步任务(是的,不幸的是,这是不可避免的)。似乎有两种方法可以实现这一点 - 每一种似乎都有效。所以我不确定哪个是最好的方法,或者是否有更好的方法。
例如:
var meetings = Task.Run(() => GetTodaysMeetingsAsync()).GetAwaiter().GetResult();
var meetings = GetTodaysMeetingsAsync().GetAwaiter().GetResult();
如果有人可以解释为什么一种方法比另一种更好,那将不胜感激。谢谢!
解决方案
当您使用Task.Run
时,委托的初始同步部分在线程池线程上运行,而只会().GetAwaiter().GetResult()
在同一线程上运行该同步部分。
UsingTask.Run(...).GetAwaiter().GetResult()
可以用作运行异步代码并同步等待它的解决方法,它不会导致异步死锁,而().GetAwaiter().GetResult()
可以。请注意,它仍然不是“安全的”,因为您可能在线程池线程中阻塞,在服务器上这可能导致线程池在负载时耗尽。
如果你想运行一个Task
返回方法,并且知道初始同步部分是微不足道的,并且你知道异步方法的其余部分不会运行 a SynchronizationContext
,只是().GetAwaiter().GetResult()
可以进行微优化,我会说只做如果你确切地知道你在做什么。
你怎么知道你在 no 下运行SynchronizationContext
?SynchronizationContext.Current
将是null
,由于以下原因之一:
- 您知道您的代码在没有应用程序模型(控制台应用程序、ASP.NET Core、Windows 服务)下运行
- 您以前在当前堆栈中使用
.ConfigureAwait(false)
了一个等待的不完整。Task
- 您已明确调用
SynchronizationContext.SetSynchronizationContext(null)
所以你看,有很多事情要考虑,所以一般来说你几乎总是想使用Task.Run(...).GetAwaiter.GetResult()
.
推荐阅读
- python - 一次安装Django rest框架项目的所有站点包
- python - 如何获取表单中的动态 html 表格条目到烧瓶?
- python - 如何摆脱csv中的第一列?
- c++ - 从存储为 Windows 资源的 png 获取 png 文件数据 (c++)
- flutter - 如何向 CustomPainter 添加投掷动画?
- java - 我无法为片段的 java 文件添加任何功能
- image-processing - 来自 Google Vision API 的 OCR 置信度得分
- google-search-console - 为什么 PageSpeed Insights 和 Search Console 之间的累积布局偏移不同?
- javascript - 如何按类名正确定位?
- mongodb - 来自少数操作的 MongoDB 聚合