【发布时间】: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