gpt4 book ai didi

c# - ASP.NET Core Controller 中的奇怪死锁情况

转载 作者:行者123 更新时间:2023-11-30 20:29:05 29 4
gpt4 key购买 nike

在我的 ASP.NET Core 应用程序中,我有一个看似非常简单的操作。它等待来自异步方法的一些值,然后将其作为 OK 结果返回:

public async Task<IActionResult> GetNextCommand()
{
var command = await LongPollManager.Instance.GetNextCommand(HttpContext.RequestAborted);
return Ok(command);
}

当我使用一些 HTTP 客户端调用此路由时,我可以在调试器中验证此异步方法是否返回所需的值并将其传递给 Ok 方法:

enter image description here

如果我让调试器继续运行,我希望在我的 HTTP 客户端中得到结果。但是客户端永远不会收到响应。

然后当我中断调试器时,我可以看到线程被某个内部锁阻塞了。您可以在当前屏幕截图中看到这一点:

enter image description here

这种行为只有在我对我的 LongPollManager 类进行了一些更改后才能看到(它实际上非常复杂并且使用了 TaskCompletionSourceConcurrentDictionaries 和 SemaphoreSlim 内部)。

令我困惑的是,阻塞的实际上不是我自己的 GetNextCommand 方法,而是阻塞似乎发生在 ASP.NET Core 内部。一旦在第 29 行执行并且我得到了我的 command 对象,我的 LongPollManager 类的所有复杂异步内容就结束了,我看不到我在 LongPollManager 可以阻止 ASP.NET Core 正确完成请求。

ASP.NET Core 在这里等什么?我的代码(运行到第 29 行而没有死锁)怎么会导致这种死锁情况?

最佳答案

如评论中所述

But with my latest changes it also contains a public Task property. Do you think this could have any side-effects when ASP.NET Core tries to serialize it?

是的。

框架将尝试调用属性来获取序列化的值。当该属性返回一个 Task 时,很可能会尝试同步序列化该任务的 .Result 属性,这将导致您的死锁。

混合异步和阻塞调用,如 .Result.Wait() 会导致死锁,应该避免。

引用 Async/Await - Best Practices in Asynchronous Programming

操作应返回在序列化时没有副作用的简单 POCO。

公共(public) Task 属性应该对序列化程序隐藏,通过属性忽略,或者应该转换为在序列化模型时不调用的方法。

关于c# - ASP.NET Core Controller 中的奇怪死锁情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46606539/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com