我的代码中存在死锁问题。
我的代码如下所示:
public async Task DoStuff(input)
{
await AsyncMethod();
//internally calls an async method, and blocks for its return. sometimes couses deadlocks.
new MyService().DoMoreStuff();
}
MyService.DoMoreStuff 实施:
DoMoreStuff()
{
return DoSuffAsyncMethod().Result;
}
此代码有时会让我在 DoSuffAsyncMethod 上遇到死锁,
在 MyService.DoMoreStuff 方法中。
但是,如果我将违规代码包装在任务中,则不再发生死锁
public async Task DoStuff(input)
{
await AsyncMethod();
await Task.Run(new MyService().DoMoreStuff());
}
更多信息
此代码在Windows服务的上下文中运行 因此,不涉及同步上下文。
我知道如何解决这个问题,但仍然不明白为什么代码会死锁。
有没有人可以建议解释混合同步异步代码的死锁,没有同步上下文?
修改
感谢您的评论。
我假设它死锁。
实际情况有点复杂,所以我简化了一点。
在 DoSuffAsyncMethod()中,我们正在调用远程异步服务,经过一段预定时间后 - 我们正在超时。
分析请求和接收服务,发现消息实际上是正确传输的。
因此,除非网络或网络框架相关问题,否则我们将陷入僵局。
我们假设它是死锁,因为一旦我们重新构建代码, DoSuffAsyncMethod 中的超时就会消失。
编辑2 代码
DoSuffAsyncMethod().Wait().Result
错了。
正确的代码是
DoSuffAsyncMethod().Result
问题是由于在调用堆栈中向下调用ConfigureAwait(true)。
感谢您的帮助。
答案 0 :(得分:2)
await
基本上意味着:“嘿thread
继续做你的事情,当我准备好时,我会要求你继续我的工作”。线索就像:“是的,但是当我完成剩下的工作时,我会来找你”。然后你问线程Wait
上一个任务,但它永远不会完成工作,因为完成它需要线程回到他身上(是的,等待它的线程......)< / p>
但是当你做的时候
await Task.Run(new MyService().DoMoreStuff());
await
之后的线程可用于恢复之前等待的任务(DoMoreStuff()
),因此他们都能够完成工作。
更多信息,可能会找到更好的解释here