【问题标题】:DisposeAsync method deadlocks when shutting down a .NET Core App关闭 .NET Core 应用程序时 DisposeAsync 方法死锁
【发布时间】:2021-10-04 13:30:18
【问题描述】:

在我的.NET 5 控制台应用程序中,我有一个实现IAsyncDisposable 的类,因为它需要调用第三方库的异步关闭方法,如下所示:

    public async ValueTask DisposeAsync()
   {
        await thirdParyLib.ShutDownAsync();
   }

当使用带有经典 using 语句的类时,这可以正常工作。

但是,当我在 .NET Core 的依赖注入机制(作为单例)中注册该类时,我遇到了问题。

特别是,当 .NET Core 应用程序停止时,DI 框架会自动(并且正确地)在所有已注册的单例实例上调用 DisposeAsync()。这将是完美的,但问题是此时代码挂在这里:

await thirdParyLib.ShutDownAsync();

我假设线程已死锁,但我不知道如何进一步诊断和解决问题。有什么想法吗?

【问题讨论】:

  • 您正在构建什么样的应用程序? ASP.NET Core 没有同步上下文,因此await 不会阻塞。桌面和 Blazor 应用会这样做,因此它们会在原始同步上下文繁忙时阻塞,例如在等待其他内容时阻塞。
  • 您可以使用调试器查看哪些线程卡住了,以及在哪些代码处卡住了。
  • @PanagiotisKanavos:它确实是一个桌面应用程序,所以我想你可能是对的。在这种情况下,我想正确的方法是在尝试处置之前取消所有其他正在访问该对象的线程?
  • @Master_T 不知道其他线程在做什么,以及它如何与ShutDownAsync() 交互 - 我们只能推测。你能提示一下thirdPartyLib 在这里吗?或者:将其作为您的供应商问题(即询问他们为什么会阻止它,以及如何解决它)?
  • @Master_T 快速而肮脏的解决方案是使用.ConfigureAwait(false)。但这是一种不寻常的情况——控制台应用程序没有同步上下文,不应该阻塞。桌面应用程序(WinForms、WPF)可以,但即便如此,为什么 UI 线程会被阻塞?你有在退出时阻塞的代码吗?

标签: c# .net-core dependency-injection .net-5 idisposable


【解决方案1】:

好吧,我在我的具体情况下找到了解决方案,即直接在第三方对象上调用Dispose(),而不是使用有问题的专用异步方法。

【讨论】:

    猜你喜欢
    • 2011-07-01
    • 2010-11-08
    • 1970-01-01
    • 2020-04-09
    • 2019-07-28
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    相关资源
    最近更新 更多