卸载AppDomain动态调用DLL异步线程执行失败
应用场景
动态调用DLL中的类,执行类的方法实现业务插件功能
使用Assembly 来实现
但是会出现逻辑线程数异常的问题
使用AppDomain 实现动态调用,并卸载。
发现问题某个插件中开启异步线程,会抛线程终止的异常。
百度查到把线程执行代码放到finally块中
AppDomain很出色的一个能力就是它允许卸载。卸载AppDomain会导致CLR卸载AppDomain中的所有程序集,还会释放AppDomain的Loader堆。为了卸载一个AppDomain,可以调用AppDomain的静态方法Unload。这导致了CLR执行一些列操作来得体地卸载指定AppDomain。
1. CLR挂起进程中执行过托管代码的所有线程
2. CLR检查所有线程栈,查看哪些线程正在执行要卸载的那个AppDomain中的代码,或者哪些线程会在某个时刻返回至要卸载的那个AppDomain。在任何一个栈上,如果准备卸载的AppDomain,CLR都会强迫对应的线程抛出一个ThreadAbortException异常(同时恢复线程的执行)。这将导致线程展开(unwind),在展开的过程中执行遇到的所有finally块中的内容,以执行资源清理代码。如果没有代码捕捉ThreadAbortException,它最终会成为一个未处理的异常,CLR会“吞噬”这个异常,线程会终止,但进程可以继续运行。这一点是非常特别的,因为对于其他所有未处理的异常,CLR都会终止进程。
重要提示:如果一个线程当前正在finally块、catch块、类构造器、临界执行区(critical execution region)域或非托管代码中执行,那么CLR不会立即终止该线程。否则,资源清理代码、错误恢复代码、类型初始化代码、关键代码或者其他任何CLR不了解的代码都无法完成,导致应用程序的行为变得无法预测,甚至可能造成安全漏洞。线程在终止时,会等待这些代码块执行完毕。然后当代码块结束时,CLR再强制线程抛出一个ThreadAbortException。
临界区是指线程终止或未处理异常的影响可能不限于当前任务的区域。相反,非临界区中的终止或失败只对出现错误的任务有影响。
3. 当上一步发现的所有线程都离开AppDomain后,CLR遍历堆,为引用了“已卸载的AppDomain创建的对象”的每一个代理都设置一个标志(flag)。这些代理对象现在知道它们引用的真实对象已经不在了。如果任何代码在一个无效的代理对象上调用一个方法,该方法会抛出一个AppDomainUnloadedException
4. CLR强制垃圾回收,对现已卸载AppDomain创建的任何对象占用的内存进行回收。这些对象的Finalize方法被调用(如果存在Finalize方法),使对象有机会彻底清理它们占用的资源
5. CLR恢复剩余所有线程的执行。调用AppDomain.Unload方法的线程将继续执行,对AppDomain.Unload的调用是同步进行的
在前面的例子中,所有工作都用一个线程来做。因此,任何时候只要调用AppDomain.Unload都不可能有另一个线程在要卸载的AppDomain中。因此,CLR不必抛出任何ThreadAbortException异常。
顺便说一句,当一个线程调用AppDomain.Unload方法时,针对要卸载的AppDomain中的线程,CLR会给它们10秒钟的时间离开。10秒后,如果调用AppDomain.Unload方法的线程还没有返回,CLR将抛出一个CannotUnloadAppDomainException异常,AppDomain将来可能会也可能不会卸载。
注意:如果调用AppDomain.Unload方法的线程不巧在要卸载的AppDomain中,CLR会创建另一个线程来尝试卸载AppDomain。第一个线程被强制抛出一个ThreadAbortException兵展开。新建的线程将等待AppDomain卸载,然后新线程会终止。如果AppDomain卸载失败,新线程将处理CannotUnloadAppDomainException异常。但是,由于我们没有写供这个新线程执行的代码,所以无法捕获这个异常。
卸载AppDomain动态调用DLL异步线程执行失败的更多相关文章
- C#程序实现动态调用DLL的研究(转)
摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...
- C#程序实现动态调用DLL的研究[转]
摘 要: 在< csdn 开发高手> 2004 年第 03 期中的<化功大法——将 DLL 嵌入 EXE >一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在 ...
- C#程序实现动态调用DLL的研究
摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...
- 【VB技巧】VB静态调用与动态调用dll详解
本文“[VB技巧]VB静态调用与动态调用dll详解”,来自:Nuclear'Atk 网络安全研究中心,本文地址:http://lcx.cc/?i=489,转载请注明作者及出处! [[请注意]]:在以下 ...
- 动态调用DLL函数有时正常,有时报Access violation的异常
动态调用DLL函数有时正常,有时报Access violation的异常 typedef int (add *)(int a,int b); void test() { hInst=LoadL ...
- 利用C#的反射机制动态调用DLL类库
最近由于业务要求,需要动态调用DLL类库,所以研究了一下,感觉还好也不太难,今天就把自己理解的写了一个小例子(已经通过VS2005跑通),供大家一起研究和探讨,有理解不当的地方还请高手们多多指正,谢谢 ...
- VC动态调用DLL
1. //函数指针声明 typedef int (_stdcall MYDLLFUN)(char* _pcOut, /*INOUT*/int *_piOutBufLen, char* _pcIn, i ...
- C#中动态调用DLL动态链接库
其中要使用两个未公开的Win32 API函数来存取控制台窗口,这就需要使用动态调用的方法,动态调用中使用的Windows API函数主要有三个,即:Loadlibrary,GetProcAddress ...
- C#中动态调用DLL动态链接库(转)
本来是想实现控制台程序运行时自动全屏,但是只找到VC下的实现方法(http://www.vckbase.com/bbs/prime/viewprime.asp?id=347). 其中要使用两个未公开的 ...
随机推荐
- LoadRunner ---协议分析
在做性能测试的时候,协议分析是困扰初学者的难题,选择错误的协议会导致Virtual User Generator 录制不到脚本:或录制的脚本不完整,有些应用可能需要选择多个协议才能完整的记录 客户端与 ...
- js中原型继承的概念
- Centos apache + mysql + usvn 配置svn 服务器
1.遇到问题 提交异常:'svn/!svn/me'path not found http://www.myexception.cn/cvs-svn/1262826.html 更改http.conf 配 ...
- linux命令(5):rm 命令
linux中删除文件和目录的命令: rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所有文件及子目录均删除.对于链接文件,只是删除了链接,原有 ...
- search 搜索
hosts文件路径 C:/WINDOWS/system32/drivers/etc/hosts host tnsnames.ora文件路径 C:/oraclexe/app/oracle/product ...
- GridLayout自定义数字键盘(两个EditText)
功能说明: 适用于两个EditText输入框,并控制输入字符的长度,点击键盘中的"确定"按钮完成输入,点击"前一项"光标跳到前一个EditText 运行效果图如 ...
- grunt 基本使用使用(一)。
使用grunt 之前,需要做一些基本工作. 1.在E盘 新建空文件夹 grunt. 2.在grunt目录下新建package.json 文件,用了存储 npm模块的依赖项.基本依赖块代码如下: { & ...
- notepad++的CoolFormat代码格式化插件使用
因为notepad++的NppAStyle插件只支持格式化C.C++.C#.Java这四种编程语言的代码,所以本人推荐使用这个CoolFormat的插件,相比于NPPAStyle,CoolFormat ...
- Windows XP SP3下编译安装check-0.10.0
软件环境:visual studio 2010 cmake-3.6.3-win32-x86 从github.com下载check-0.10.0到本地,解压出目录check-0.10.0 下载cmake ...
- android opengl es代码功能
/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Versi ...