英文原文:https://guiferreira.me/archive/2020/08/avoid-getawaiter-getresult-at-all-cost/
当您需要等待Task时,您是否在同步方法中使用“.GetAwaiter().GetResult()”而不是“.Result”和“.Wait()”? 你正在做比较正确的事,但前提是您无法改变该方法!
与 Task.Wait 和 Task.Result 相比,Task.GetAwaiter().GetResult() 更受青睐,因为它会传播异常,而不是将异常包裹在 AggregateException 中。但是,这三种方法都有可能造成死锁和线程池饥饿问题。应避免使用这三种方法,而应使用 async/await。
//Task.Result;
//Task.Wait();
Task.GetAwaiter().GetResult();
如果您不知道,在 C# 中,当您有Task时,您应该始终致力于使用 async/await。 你应该一直使用 async/await。
如果您使用“.GetAwaiter().GetResult()”、“.Result”或“.Wait()”来获取任务结果或等待任务完成,您可能会遇到死锁或线程池饥饿。
因此,我建议您尽量避免使用".GetAwaiter().GetResult()“、”.Result “或”.Wait()"。从上到下重构代码,使用 async/await。将其作为一种代码气味,让人知道在压力下可能会出错。你会发现,在压力下,系统会表现得更好。
如果我无法使用 Async/Await 该怎么办?
这个问题很有道理。有时我们需要 “同步胜于异步”。
有两种简单的情况:
- 您在构造函数中有一个任务;
- 需要尊重您无法控制的接口;
在这种情况下,我建议您只使用一次".GetAwaiter().GetResult()"。提取一个您的公共方法可以依赖的私有异步方法。