的任务.WaitAll与async/await任务挂起
本文关键字:任务 await 挂起 WaitAll async | 更新日期: 2023-09-27 18:17:44
我一定错过了一些明显的东西,如SynchronizationContext
上的死锁,但我不明白为什么会发生这种情况,也不明白我如何避免它…
所以,应用程序是Azure WorkerRole(本质上,据我所知,通常的Windows应用程序没有UI)。在应用程序中,我试图并行执行许多任务,我的代码的示意图版本是这样的:
private async Task DoJob()
{
await SomeIoOperation();
}
public void MethodExecutedByWorkerRoleInAnInfiniteLoop()
{
Log("Start");
Task.WaitAll(DoJob(), DoJob(), DoJob());
Log("End");
}
我的想法是,我们在这里操作默认的SynchronizationContext
,所以我们应该避免死锁,我们会在类似的情况下,例如,在ASP.NET。
然而,有时执行挂起-开始被记录,结束不是几天,直到我重新启动工作者角色。当然,DoJob不可能运行那么长时间。奇怪的是,这不会在worker角色启动后立即发生——它可能需要几天或几周的正常操作才能挂起。
我可以简化代码太多-也许这是重要的到底发生了什么在SomeIoOperation
-但我觉得这是明显相关的SynchronizationContext
滥用。
SomeIoOperation.ConfigureAwait(false)
会有帮助吗?我甚至不能测试它,因为我不知道它是否正在工作,因为问题已经修复,或者在几天后最终会挂起。
想法?
你确实在SynchronizationContext上陷入了死锁。用WhenAll
代替WaitAll
:
public async Task MethodExecutedByWorkerRoleInAnInfiniteLoop()
{
Log("Start");
await Task.WhenAll(DoJob(), DoJob(), DoJob());
Log("End");
}