何时使用Task.Run()。GetAwaiter()。GetResult()和().GetAwaiter.GetResult()?

时间:2019-11-24 14:10:06

标签: c# .net asynchronous .net-core task

我有一个异步任务,需要同步调用(是的,不幸的是,这是不可避免的)。似乎有两种方法可以实现此目的-每种方法似乎都有效。因此,我不确定哪种方法最好,或者是否有更好的方法。

例如:

var meetings = Task.Run(() => GetTodaysMeetingsAsync()).GetAwaiter().GetResult();

var meetings = GetTodaysMeetingsAsync().GetAwaiter().GetResult();

如果有人可以解释为什么一种方法比另一种更好,那将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:4)

使用public struct NavigationBarHider: ViewModifier { @State var isHidden: Bool = false public func body(content: Content) -> some View { content .navigationBarTitle("") .navigationBarHidden(isHidden) .onAppear { self.isHidden = true } } } extension View { public func hideNavigationBar() -> some View { modifier(NavigationBarHider()) } } 时,委托的初始同步部分在线程池线程上运行,而仅Task.Run将在同一线程上运行该同步部分。

使用().GetAwaiter().GetResult()可以作为一种解决方法来运行异步代码并同步等待它,它不会导致异步死锁,而Task.Run(...).GetAwaiter().GetResult()可以。请注意,它仍然不是“安全”的,因为您可能会在服务器上的线程池线程中进行阻塞,这可能导致负载时线程池耗尽。

如果您要运行().GetAwaiter().GetResult()返回方法,并且知道初始同步部分是微不足道的,并且您知道async方法的其余部分将不会与{ {1}},只是Task可以是一个微优化,我只想在您完全知道自己在做什么的情况下才这样做。

您怎么知道自己没有SynchronizationContext奔跑?由于以下原因之一,().GetAwaiter().GetResult()将为SynchronizationContext

  • 知道您的代码正在没有任何应用程序模型(控制台应用程序,ASP.NET Core,Windows服务)下运行
  • 您以前在当前堆栈中已使用SynchronizationContext.Current来等待null
  • 您已明确致电.ConfigureAwait(false)

因此,您发现,要考虑很多事情,因此,通常来说,您几乎总是想使用Task