.Wait()与.GetAwaiter()。GetResult()有什么区别?


88

我的方法返回Task。我要等到完成。我应该使用 .Wait().GetAwaiter().GetResult()?它们之间有什么区别?

Answers:


107

两者都是同步等待操作的结果(如果可能,应避免使用它们)。

区别主要在于处理异常。使用Wait,异常堆栈跟踪不会更改,并表示发生异常时的实际堆栈,因此,如果您有一段在线程池线程上运行的代码,则将有一个类似

ThreadPoolThread.RunTask
YourCode.SomeWork

另一方面,.GetAwaiter().GetResult()将重做堆栈跟踪以考虑所有异步上下文,而忽略代码的某些部分在UI线程上执行,而某些部分在ThreadPool线程上执行,而某些只是异步I / O。因此,您的堆栈跟踪将反映出代码中类似同步的步骤:

TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork

至少可以这样说,这倾向于使异常堆栈跟踪更有用。您可以看到在应用程序上下文YourCode.SomeWork被调用的位置,而不是“运行它的物理方式”。

参考来源(当然是非合同的)是一个如何工作的示例。


6
Task.GetAwaiter() 返回TaskAwaiter。但是,TaskAwaiter.GetResult()的文档建议:“此API支持产品基础结构,不能直接在您的代码中使用。” 你能发表评论吗?
DavidRR

23
@DavidRR整个TaskAwaiter都是实现细节。另一方面,等待/等待机制已记录在案,并使用鸭式输入法-GetAwaiterawait原样GetEnumerator对toforeachDispose对to using。所有这些都在C#规范中定义,而不管使用的是哪个特殊的等待者-请注意,Task.GetAwaiter“旨在供编译器使用,而不是用于应用程序代码中”。但要点是,预期用途是执行await,而Wait()不是GetAwaiter().GetResult()-而是GetResult在需要时提供更好的堆栈。
a安
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.