第三节:卸载AppDomain

AppDomain很出色的一个能力就是它允许卸载。卸载AppDomain会导致CLR卸载AppDomain中的所有程序集。还会释放AppDomain的Loader堆。为了卸载一个AppDomain,可调用AppDomain的静态方法Unload。这将导致CLR执行一系列操作来得体的卸载指定AppDomain。

  1. CLR挂起进程中执行过托管代码的所有线程。
  2. CLR检查所有线程栈,查看那些线程正在执行要卸载的那个AppDomain中的代码,或者那些线程会在某个时候返回至要卸载的那个AppDomain。在任何一个栈上,如果有准备卸载的AppDomain,CLR会强迫对应的线程抛出一个ThreadAbortException异常(同时恢复线程的执行)。这将导致线程展开,在展开的过程中执行遇到的所有finally块中的内容,以执行资源清理代码。如果没有代码捕捉ThreadAbortException,它最终会成为一个未处理的异常,CLR会“吃掉”这个异常;

线程会终止,但进程可继续运行。这一点是非常特别的,因为对于其他所有未处理的异常,CLR都会终止进程。

  1. 当第2步发现的所有线程都离开AppDomain后,CLR遍历堆,为引用了”由已卸载的APPDomain创建的对象”的每一个代理对象都设置一个标志。这些代理对象现在知道他们引用的真实对象已经不在了。如果任何代码在一个无效的代理对象上调用一个方法,该方法会抛出一个AppDomainUnloadedException。
  2. CLR强制垃圾回收,对现已卸载AppDomain创建的任何对象占有的内存进行回收。这些对象的Finalize方法被调用,使对象有机会彻底清理他们所占用的资源。
  3. CLR恢复剩余所有线程的执行。调用AppDomain.Unload方法的线程将继续运行;对AppDomain.Unload的调用时同步进行的。

在Ch22-1-AppDomain应用程序中,所有工作都有一个线程来做。因此,任何时候只要调用AppDomain.Unload,都不可能有另一个线程在要卸载的AppDomain中。因此,CLR不必抛出任何ThreadAbortException异常。

顺便说一句,当一个线程调用AppDomain.Unload方法时,针对要卸载的AppDomain中的线程,CLR会给他们10秒钟的时间离开。10秒钟之后,如果调用AppDomain.Unload方法的线程还没有返回,CLR将抛出一个CannotUnloadAppDomainException异常,AppDomain将来可能会、也可能不会卸载。

时间: 2024-10-19 16:29:41

第三节:卸载AppDomain的相关文章

CLR via C#读书笔记 CLR寄宿和AppDomain

寄宿 寄宿是指让其他应用程序(非托管代码)使用CLR的能力,比如自己用C++开发的窗体能创建CLR实例. 托管代码也能调用非托管代码 [DllImport("kernel32.dll")] public static extern int WinExec(string exeName, int operType); 通常会调用win32 api,但是要查文档才知道怎么定义extern方法 CLR实际上被实现为COM服务器,可以通过CoCreateInstance或CLRCreateIn

.Net AppDomain详解(二)

AppDomain 类 表示应用程序域,它是一个应用程序在其中执行的独立环境. 此类不能被继承. 命名空间:   System程序集:  mscorlib(位于 mscorlib.dll) 继承层次结构 System.Object??System.MarshalByRefObject????System.AppDomain [ClassInterfaceAttribute(ClassInterfaceType.None)] [ComVisibleAttribute(true)] public s

C#动态加载/卸载Assembly的解决方案

1.  Assembly中的类要从MarshalByRefObject继承,如果你想从你自己的类来继承,那么请选用interface或者继续研究其他解决方案. namespace Library { public class MyClass : MarshalByRefObject { } } 其中MyClass的方法的返回值和参数必须是简单类型或者可序列化的.2. 调用程序中,实现一个加载Assembly的辅助类,比如叫做LoadHelper,它也从MarshalByRefObject继承.在

【C#进阶系列】22 CLR寄宿和AppDomain

关于寄宿和AppDomain 微软开发CLR时,将它实现成包含在一个DLL中的COM服务器. 任何Windows应用程序都能寄宿(容纳)CLR.(简单来讲,就是CLR在一个DLL中,通过引用这个DLL,可以实现包含CLR) CLR COM服务器初始化会创建一个默认AppDomain,这个AppDomain只有在进程终结时才会被销毁. 然而宿主程序还可以要求CLR创建额外的AppDomain. 因为创建进程开销很大,并且需要大量内存来虚拟化进程的地址空间. 所以人们就像可不可以在一个进程上运行多个

第二节:AppDomain

CLR COM服务器初始化时,会创建一个AppDomain.AppDomain是一组程序集的逻辑容器.CLR初始化时创建的第一个AppDomain称为默认的AppDomain,这个默认的AppDomain只有在Windonws进程终止时才能被撤销. 除了默认的AppDomain,正在使用非托管Com接口方法或托管类型方法的一个宿主还可指示CLR创建额外的AppDomain,AppDomain唯一的作用就是进程隔离.下面总结了AppDomain的具体功能. 1.1.   一个AppDomain中的

AppDomain 的作用

AppDomain 类似于一个轻量级进程,它是 .net / mono 代码运行时的一个逻辑容器. 一般情况下,我们开发的代码都运行在"运行时"为我们创建的 AppDomain 中(即默认 AppDomain),察觉不到 AppDomain 的存在,也不太需要关注 AppDomain.但在另外一些情况下,有可能需要在应用程序中创建其他 AppDomain,例如: 动态卸载程序集:我们知道在 .net / mono 中,可以在运行时动态加载程序集,但却无法将已加载到内存的特定程序集卸载掉

第22章 CLR寄宿和AppDomain

寄宿允许使任务应用程序都能利用CLR的功能.寄宿(hosting)允许使任务应用程序都能利用CLR的功能.另外,寄宿还为应用程序提供了通过编程来进行自定义和扩展能力.AppDomain允许第三方的,不受信任的代码在一个现有的进程中运行,而CLR保证数据结构.代码和安全上下文不会被滥用或破坏. 22.1 CLR寄宿 CLR Hosting(CLR 宿主)的概念:初始启动.Net Application时,Windows进程的执行和初始化跟传统的Win32程序是一样的,执行的还是非托管代码,只不过由

第六节:宿主如何使用AppDomain

前面已经讨论了宿主以及宿主加载CLR的方式.同时还讨论了宿主如何告诉CLR创建和卸载AppDomain.为了使这些讨论更加具体,下面将描述一些常见的宿主和AppDomain使用情形.特别地,我要解释不同应用程序类型如何宿主CLR,以及他们如何管理AppDomain. 1      可执行应用程序 控制台UI应用程序.NT Service应用程序.Windows窗体应用程序和WPF应用程序都是自宿主应用程序的例子,他们都有托管的EXE文件.Windows用一个托管EXE文件初始化一个进程时,会加载

C# AppDomain 类

/*** AppDomain 表示应用程序域,它是一个应用程序在其中执行的独立环境.无法继承此类. 应用程序域(由 AppDomain 对象表示)为执行托管代码提供隔离.卸载和安全边界. 使用应用程序域隔离可能终止进程的任务.如果正在执行任务的 AppDomain 的状态变得不稳定, 则可以卸载 AppDomain,但不会影响进程.当进程必须不重新启动而长时间运行时,这一点很重要. 还可使用应用程序域隔离不应共享数据的任务. 如果程序集被加载到默认应用程序域中,则当进程运行时将无法从内存中卸载该