【问题标题】:Find offending thread causing CannotUnloadAppDomainException查找导致 CannotUnloadAppDomainException 的违规线程
【发布时间】:2016-09-22 01:22:52
【问题描述】:

在我的 C# .Net 4.0 项目中,我使用 AppDomains 加载插件程序集,让它们工作,然后卸载 AppDomain,这样我就不必将程序集保留在主进程中。

对于一个特定的插件,当我调用AppDomain.Unload() 时,我会得到一个CannotUnloadAppDomainException。我发现这很可能是因为插件在catchfinally 块中启动了一个后台线程,该线程要么被卡住,要么花费很长时间(~10 秒)。不幸的是,我不知道线程在哪里。

这只发生在客户的机器上,所以我无法使用调试器提供帮助。但是,如果我能找到更有用的东西来写出,我可以给他们一个补丁来将更多信息写入日志文件。

我有插件程序集的源代码,我一直在尝试做一些静态分析并运行一些测试,但它非常大,我没有运气找到它卡在 @987654325 的地方@ 或finally

我的问题:

  1. 有没有什么方法可以在获得CannotUnloadAppDomainException 时获得在子 AppDomain 中使用其调用堆栈运行的线程列表?

  2. 除了catchfinally 块之外,还有其他代码段可以抛出此异常吗?

【问题讨论】:

    标签: c# .net appdomain


    【解决方案1】:

    让客户端运行PerfView 以在程序发生时获取程序的 ETW 跟踪,它应该让您获得有关在异常发生的确切时刻正在运行的内容的更详细信息。这是a set of video tutorials from Channel 9,告诉你如何使用它。

    【讨论】:

      【解决方案2】:

      使用this post(这是NuGet package)中提到的Microsoft.Diagnostics.Runtime 库,当子AppDomain 的函数即将返回时,我能够列出所有仍在运行的线程及其调用堆栈。我确实必须将我的应用程序临时升级到 .NET 4.5 才能与该库一起运行,但该库的源代码是 available on GitHub,因此可以使用 <.net> 构建此库

      事实证明,这是处理我们的数据库连接的第三方库中的一个错误,当数据库在本地计算机上使用 SSL 时,会留下几个锁定的线程。

      【讨论】:

      • 我们在运行 Windows 服务的 win 2012 服务器上遇到了类似的问题 - 奇怪的是,当相同的代码在 win 10(即使作为服务)上运行时,CannotUnloadAppDomainException 没有出现。我们有一个非后台线程留在应用程序域中;清理退出线程解决了我们的问题
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 2011-11-29
      • 1970-01-01
      相关资源
      最近更新 更多