我的方法返回Task
。我要等到完成。我应该使用
.Wait()
或.GetAwaiter().GetResult()
?它们之间有什么区别?
我的方法返回Task
。我要等到完成。我应该使用
.Wait()
或.GetAwaiter().GetResult()
?它们之间有什么区别?
Answers:
两者都是同步等待操作的结果(如果可能,应避免使用它们)。
区别主要在于处理异常。使用Wait
,异常堆栈跟踪不会更改,并表示发生异常时的实际堆栈,因此,如果您有一段在线程池线程上运行的代码,则将有一个类似
ThreadPoolThread.RunTask
YourCode.SomeWork
另一方面,.GetAwaiter().GetResult()
将重做堆栈跟踪以考虑所有异步上下文,而忽略代码的某些部分在UI线程上执行,而某些部分在ThreadPool线程上执行,而某些只是异步I / O。因此,您的堆栈跟踪将反映出代码中类似同步的步骤:
TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork
至少可以这样说,这倾向于使异常堆栈跟踪更有用。您可以看到在应用程序上下文中YourCode.SomeWork
被调用的位置,而不是“运行它的物理方式”。
参考来源(当然是非合同的)是一个如何工作的示例。
TaskAwaiter
都是实现细节。另一方面,等待/等待机制已记录在案,并使用鸭式输入法-GetAwaiter
按await
原样GetEnumerator
对toforeach
或Dispose
对to using
。所有这些都在C#规范中定义,而不管使用的是哪个特殊的等待者-请注意,Task.GetAwaiter
“旨在供编译器使用,而不是用于应用程序代码中”。但要点是,预期用途是执行await
,而Wait()
不是GetAwaiter().GetResult()
-而是GetResult
在需要时提供更好的堆栈。