的任务.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)会有帮助吗?我甚至不能测试它,因为我不知道它是否正在工作,因为问题已经修复,或者在几天后最终会挂起。

想法?

的任务.WaitAll与async/await任务挂起

你确实在SynchronizationContext上陷入了死锁。用WhenAll代替WaitAll:

public async Task MethodExecutedByWorkerRoleInAnInfiniteLoop()
{
    Log("Start");
    await Task.WhenAll(DoJob(), DoJob(), DoJob());
    Log("End");
}