C#/ASP.NET 核心:这是 .Wait() 的正确用法吗?

C#/ASP.NET Core: Is this proper usage of .Wait()?

上下文:

我们有一个带有接口和整个 shabang 的大继承树。我们向工厂提供请求,工厂创建适当的对象,然后我们调用所有这些对象公开的 DoStuff() 方法。该方法没有 return 任何东西,只是设置了一些属性。

问题:

仅在一个案例中,在 DoStuff() 方法内部,我们必须调用一个异步方法,但没有办法解决它,因为我们无法控制该方法。重构整个继承树以将 DoStuff() 方法转为使用异步任务签名并不是我们所期待的。

我们可以在操作完成之前阻塞线程。

问题:

我们尝试在该方法上使用 RunSynchronously(),但出现以下错误:

System.InvalidOperationException: RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Threading.Tasks.Task.InternalRunSynchronously(TaskScheduler scheduler, Boolean waitForCompletion)

我们应该改用 Wait() 吗?

这取决于您是否对缺点感到满意。这是一个 web 应用程序,因此您希望尽可能保持线程空闲,但是通过使用 .Wait() 您可以在异步方法中用于延续(或线程绑定)的任何线程之上获得一个额外的线程不可用任务,对于网络应用程序来说又不是典型的)。

但是,如果这是您所担心的,您将不会看到任何死锁。 ASP.NET 核心不使用非默认值 SynchronizationContext,因此您不会锁定,但请注意,这是无法应对负载的滑坡,因为这比同步版本。

如果这是常规的 ASP.NET,如果 async 方法中的任何 await 没有使用 ConfigureAwait(false),您会看到死锁(不完全是如此黑白分明,但这已经足够接近真相了。