C# Task.WaitAll与异步/等待任务挂起
我肯定错过了一些明显的事情,比如C# Task.WaitAll与异步/等待任务挂起,c#,azure,asynchronous,async-await,task-parallel-library,C#,Azure,Asynchronous,Async Await,Task Parallel Library,我肯定错过了一些明显的事情,比如SynchronizationContext上的死锁,但我不明白为什么会发生这种情况,也不明白如何避免它 因此,应用程序是Azure WorkerRole(据我所知,基本上是没有UI的普通Windows应用程序)。在应用程序中,我尝试并行执行许多任务,我的代码的原理图版本如下: private async Task DoJob() { await SomeIoOperation(); } public void MethodExecutedByWork
SynchronizationContext
上的死锁,但我不明白为什么会发生这种情况,也不明白如何避免它
因此,应用程序是Azure WorkerRole(据我所知,基本上是没有UI的普通Windows应用程序)。在应用程序中,我尝试并行执行许多任务,我的代码的原理图版本如下:
private async Task DoJob()
{
await SomeIoOperation();
}
public void MethodExecutedByWorkerRoleInAnInfiniteLoop()
{
Log("Start");
Task.WaitAll(DoJob(), DoJob(), DoJob());
Log("End");
}
我的想法是,我们在这里使用默认的SynchronizationContext
,因此我们应该避免类似情况下的死锁,例如在ASP.NET中
但是,有时执行挂起-记录开始,在我重新启动工作角色之前的几天内不会结束。当然,DoJob不可能运行那么长时间。奇怪的是,这并不是在工作人员角色启动后立即发生的——可能需要几天或几周的正常操作才能挂起
我可能过于简化了代码-也许在SomeIoOperation
中到底发生了什么很重要-但我觉得这显然与SynchronizationContext
误用有关
是否将SomeIoOperation.configurewait(false)
help?我甚至无法测试它,因为我不知道它是否有效,因为问题已经解决,或者在几天后最终会挂起
想法?您在SynchronizationContext上完全陷入了死锁。 只需使用
whalll
而不是WaitAll
:
public async Task MethodExecutedByWorkerRoleInAnInfiniteLoop()
{
Log("Start");
await Task.WhenAll(DoJob(), DoJob(), DoJob());
Log("End");
}
所有这些都会起作用。本文将向您介绍原因加载项
Log(SynchronizationContext.Current)如果不是null
,您就会知道SynchronizationContext
有问题DoJob
将始终希望同步到调用上下文。不管什么上下文SomeIoOperation
使用哪种上下文。@Gusdor,我已经读了很多文章了。。。它们清楚地解释了为什么该问题会出现在Windows UI或ASP.NET应用程序中。据我所知,我的情况并非如此。@MichaelSagalovich您知道这会阻止文章应用于此情况吗?此方法是在循环中执行的-调用方希望知道该方法何时完成。在国际海事组织,本次修订应返回任务
。谢谢。我只是忘了在任务上更改void。但是在我的循环中,我将不得不执行由WorkerRoleInInfiniteLop()执行的方法。Wait()
-它不会导致死锁吗?据我所知,Microsoft.WindowsAzure.ServiceRuntime
中没有异步版本的RoleEntryPoint
,因此我无法在任何地方等待WorkerRoleInfiniteLop执行的方法。@MichaelSagalovich如果你想使用Wait
,你应该一路重构你的代码使之异步。@Gusdor,我知道这一点,并正在研究如何使用它。尽管如此,我还是很想知道为什么会出现我认为不应该出现的僵局。