我的方法返回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在需要时提供更好的堆栈。