如果在异步调用中调用阻塞方法会发生什么情况?



如果您正在制作一个支持 aysnc 的应用程序,并且您必须与仅提供阻塞方法的第三方库进行交互,那么当async方法阻塞时会发生什么?

一个简单的例子是在.Net Framework中,Socket.Receive允许您设置超时,但随后阻止。如果第 3 方库包装了它,而我在异步方法中调用它是否仅仅意味着运行时分配给Task的任何线程都被阻止了?它会阻止其他任务或产生其他副作用吗?

async方法中阻止没有错。 不过,这其中也有影响。

如果在由 UI事件调用的async void方法中阻止,则还将阻止 UI 线程并使 UI 无响应。

当您在async Task方法或任何Task中阻塞时,您当然会阻止当前运行该方法的这一部分或此任务的线程。 如果并发运行此任务的许多实例,或者并发执行方法(例如,它是许多客户端调用的服务方法(,则可能会耗尽线程池。 这可以阻止其他任务运行,或阻止其他客户端调用您的服务。

如果要避免后一种情况,则可能值得在长时间运行的 Task 中运行此阻止方法。 .Net 中的当前实现将为此任务创建一个单独的线程,因此不会阻止线程池中的线程。

如果第 3 方库包装了它并且我在异步方法中调用它是否仅意味着运行时分配给任务的任何线程都被阻止了?

是的。充其量它会阻塞您的任务线程,最坏的情况是,如果您处于任何Synchronization Context(Desktop GUIASP.NET Request Threads before .Net Core(,您将陷入死锁!

它会阻止其他任务或产生其他副作用吗?

如果通过名为 T 的线程包装阻塞方法,该线程的定义类似于Task.Run(/* Blocking method */)它将阻塞T

最新更新