【发布时间】:2013-08-22 16:55:14
【问题描述】:
我在 4.5 中遇到了一些异步代码的死锁问题。我读了Stephen Cleary's blog about preventing deadlocks that occur when the task captures the executing context 然后在相同的上下文中你通过等待任务来阻止。我试图实施该解决方案,但我仍然遇到死锁,我不明白为什么。
原始代码
消费类:
private void Update(...)
{
//... do some stuff ...
_repository.Save(listing).Wait();
}
返回任务的类:
protected override Task Save(...)
{
return Task.Run(() =>
{
... do some stuff ...
_logger.Debug("All Done!!!");
});
}
修改后的代码
消费类:
private void Update(...)
{
//... do some stuff ...
_repository.Save(listing).Wait();
}
返回任务的类:
protected override async Task Save(...)
{
await Task.Run(() =>
{
... do some stuff ...
_logger.Debug("All Done!!!");
}).ConfigureAwait(false);
}
即使在修改后的版本中,我明确告诉等待的任务不要绑定到上下文,我仍然会遇到死锁。
有什么想法吗?
【问题讨论】:
-
ConfigureAwait只是当您不能使用await时的一种解决方法。最好的解决方案肯定是让Update成为async Task方法;有什么理由这行不通吗? -
看起来
Save需要await而你的lambdaTask需要async。 -
我的 Update 方法是一个 WebApi IHttpController。让控制器返回异步无效或异步任务会更好吗?感谢斯蒂芬的快速回复
-
没关系,我看到你的博客给出了一个返回异步任务的控制器方法示例
-
让我担心的是,我们实际上还有其他代码在使用同一个存储库。Save 方法然后调用 .Wait,但其他代码没有死锁,也没有标记为异步。我在我们的代码库中进行了搜索,我们到处都有数百个 .Wait 调用,但这是我们第一次看到死锁。我正在尝试尽可能多地了解这个问题,以防我们开始在其他地方看到它。
标签: c# .net asynchronous .net-4.5 async-await