ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – .NET AppDomain.Unload触发失控线程

2019-05-29 07:53:47  阅读:354  来源: 互联网

标签:c net multithreading appdomain


我有一个.NET 3.5 SP1应用程序,它是一个Excel加载项.应用程序分为父AppDomain(Excel)和子域,我们在其中加载所有dll.当我们希望更新我们的应用程序时,我们卸载子域,替换文件并重新加载它.

不幸的是,卸载域将激活2个工作线程,并且它们将开始消耗CPU周期(20-40%).

如果我使用VS 2010进行调试,那么在AppDomain.Unload之前和之后,除了Excel的主线程之外,没有线程可以使用调用堆栈.确实卸载了AppDomain.Unload,因为如果我再次尝试调用Unload,我会收到AppDomainUnloadedException.

如果我使用ProcessExplorer,我可以看到2个线程正忙着工作,即使VS调试器已经破坏.看着callstack没有显示任何东西,因为没有符号.

> ntkrnlpa.exe 0x6eacb
> ntkrnlpa.exe 0x2bfd0
> hal.dll 0x2ef2
> ntkrnlpa.exe 0x6a6cf
> ntdll.dll 0xe514
> mscorwks.dll 0x992d
> mscorwks.dll 0x52568
> mscorwks.dll 0x15b469
> kernel32.dll 0xb729

如果我使用WinDbg,我可以看到2个renegade线程的callstack.它总是一样的:

>警告:堆栈展开信息不可用.以下框架可能是错误的.
> ntdll!KiFastSystemCallRet
> mscorwks 0x992d
> mscorwks!InstallCustomModule 0x1eca0
> mscorwks!CorExitProcess 0x503b
> kernel32!GetModuleFileNameA 0x1ba

我创建了一个非常简单的测试应用程序来加载/卸载子程序集.使用简单的1级装配执行此操作时,它可以正常工作.如果我让它加载/卸载真实应用程序的子域,它会触发相同的renegade线程.

创建子域的代码如下:

AppDomainSetup appSetup = new AppDomainSetup();
appSetup.ApplicationBase = baseDir;

var ps = new PermissionSet(System.Security.Permissions.PermissionState.Unrestricted);
return AppDomain.CreateDomain(name, null, appSetup, ps, null);

从父域到子域的通信是通过代理和反射进行的.创建它的代码如下:

string assName = typeof(ApplicationProxy).Assembly.FullName;
string className = typeof(ApplicationProxy).FullName;

var obj = _childDomain.CreateInstanceAndUnwrap(assName, className, false, 
    System.Reflection.BindingFlags.Default,
    null, new object[]{_sessionGuid}, 
    CultureInfo.InvariantCulture,
    null, new Evidence(AppDomain.CurrentDomain.Evidence));

_proxy = (ApplicationProxy)obj;

我已经大量搜索了这个问题,找不到任何有类似问题的人.该应用程序是10个项目大,所以我不能发布它.

我想知道是否有人遇到类似的东西,并有一些提示给我.否则有人对如何解决问题有任何想法吗?

解决方法:

感谢Hans让我走上了正确的道路.

有一些带有终结器的类,所以我在每个类中都加了一个断点.在其中一个中,有人调用ThreadPool.QueueUserWorkItem.工作项永远不会被调用,而是留下这两个线程(1个中止正在执行的线程,1个来完成东西)永远循环.

我在我的测试项目中进行了测试,确实如此.

孩子们,教训是不让经理编写线程代码.

标签:c,net,multithreading,appdomain
来源: https://codeday.me/bug/20190529/1176456.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有