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)
,您会看到死锁(不完全是如此黑白分明,但这已经足够接近真相了。
上下文:
我们有一个带有接口和整个 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)
,您会看到死锁(不完全是如此黑白分明,但这已经足够接近真相了。