dotnet学习笔记三 - 程序域程序集

大部分开发技术和环境都定义了自己的代码执行和资源所有的范围。操作系统是以进程为范围的, IIS , ASP , JSP 是以一个虚拟目录( Virtual Directory )为范围的。而 .NET 的公共语言运行时( CLR )是以应用程序域( AppDomain )为基础范围的。

程序域基本和进程的概念相同,是代码运行和资源访问的限制区域。普通的 win32 应用的资源和地址空间是在进程内共享的。 .NET 中所有的对象和资源只能在 AppDomain 的范围中访问,对象不能在其他的 AppDomain 中访问。这样的做法保证了应用运行的安全性,防止有意和无意的代码破坏,也能防止由于某个 AppDomain 的崩溃导致其他 AppDomain 的崩溃。不过这个前提是保证代码是托管的( Managed )。如果是非托管的代码,比如使用指针,理论上就可以访问整个进程的内存空间,就可能导致无法预料的事情发生。 AppDomain 比进程来说消耗资源要少一些。每一个进程操作系统要分配一个内核对象,分配地址空间。不过相对于进程间的互相访问(也要使用一些比较特殊的方式来实现,如 Windows 消息,内存映射等)来说, AppDomain 之间的互相访问要困难一些。不过 AppDomain 是以进程为宿主的。一个进程可以有多个 AppDomain 。

使用 .NET 提供的 AppDomain 类,我们可以创建自己的 AppDomain 。如下面的代码示例:

代码 1


namespace ConsoleApp li cation1

{

///

1<summary>
2
3///  Summary description for Class1. 
4
5///  </summary>

class Class1

{

///

1<summary>
2
3///  The main entry point for the app  li  cation. 
4
5///  </summary>

[STAThread]

static void Main ( string [] args)

{

//

// TODO: Add code to start app li cation here

//

Console.WriteLine( "CurrentDomain Name is: {0}", AppDomain.CurrentDomain.FriendlyName );

AppDomain newDomain = AppDomain.CreateDomain( "New Domain", null , null );

newDomain.ExecuteAssembly( "ConsoleApp li cation2.exe" );

}

}

}

使用 AppDomain 类的静态变量 CurrentDomain 可以得到当前 AppDomain 的引用。使用静态函数 CreateDomain 可以创建新的 AppDomain 。 ExecuteAssembly 可以执行某个程序集。上面代码中的两个 AppDomain : CurrentDomain 和 newDomain 就在同一个进程中,这一点可以通过 Windows 任务管理器察看进程数得到,运行时系统进程数只增加了一。

程序集( Assembly )类似于普通程序的模块,可以是一个或者多个 Exe 和 Dll 文件。 Assembly 有私有和全局之分,私有的 Assebmly 只要放在程序的 home 目录下就可以了。公共 Assembly 则必须要有强名称,利用 .NET 提供的工具安装到系统中。

每个 AppDomain 都有自己的 Assembly 的副本,不管他们是不是在同一个进程内。如下图:

这个并不是绝对的,用户可以通过设置 CLR 来确定是否进程内的 AppDomain 可以共享某一个程序集,这样就节省了资源,提高了速度,但同时就丧失了安全性。

Assembly 一旦载入是不能被卸载的,除非它所在的程序域被卸载。我们可以通过编程来卸载 AppDomain 。就代码 1 中的 newDomain ,我们就可以使用 AppDomain.Unload(newDomain) 的语句来卸载它。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus