进程、应用程序域、程序集、对象上下文
2010-08-03 16:01 elivsit 阅读(742) 评论(0) 编辑 收藏 举报简单的说,进程可以承载一组相关的.NET程序集,而应用程序域(简称AppDomain)是对该进程的逻辑细分。一个应用程序域进一步被细分成多个上下文边界,这些边界用来分组目的相似的.NET对象。使用上下文的概念,CLR便能够确保恰当地控制那些带特殊运行时要求的对象。
传统的进程
用来描述一组资源和程序运行所必需的内存分配。对于每个被加载到内存的可执行程序,在她的生命周期中操作系统会为之单独且隔离的进程。由于一个进程的失败不会影响其他的进程,使用这种方式,运行库环境将更加稳定。
通过任务管理器,我们可以查看机器上正在运行进程的统计信息:进程的标示符(PID)以及映像名称。
进程从来不执行任何东西,它只是线程的容器。若要使进程完成某项操作,它必须拥有一个在它的环境中运行的线程,此线程负责执行包含在进程的地址空间中的代码。
线程概述
线程是进程中的基本执行单元(a path of execution)。进程的入口点创建的第一个线程为主线程。仅仅包含一个主线程的进程是线程安全的。但是,单线程的应用程序用户响应不好。
开发者使用多线程,有助于改善程序的总体响应。Win32 API可以让主线程使用如CreateThread()之类的函数,另外产生次线程。每个线程都是进程中的一个独立执行单元(unique of execution)。比如:一个应用程序可以产生一个工作线程来执行强度大的工作(比如传输大文件),当这个次线程正在忙碌的时候,主线程仍然可以对用户的输入保持响应。
当然,如果单个进程中的线程过多的话,性能反而会下降,因为CPU需要花不少时间在这些活动线程的来回切换上。另外,单CPU的计算机并没有能力同一时间运行多个线程。当一个县城的时间片用完的时候,他会被挂起(suspended),以便执行其他的线程。(找详细点的资料)
如果觉得太复杂,那么只需要记住:线程是Win32进程的独立执行的单元,每一个进程都有一个主线程,并且每个进程还可以以编程的方式创建额外的线程。
.NET平台下与进程进行交互
.NET的基类库可以方便的和进程进行交互。他们位于System.Diagnostics命名空间中,该空间定义了许多的类型,允许我们与系统进程、事件日志和性能计数器进行交互。
我们可以看到,与进程打交道的类型有:Process、ProcessModule、ProcessModuleCollection、ProcessStartInfo、ProcessThread、ProcessThreadCollection。
详细的关于Process使用方法可以查阅MSDN,比如获取/设置进程优先级,获取进程打开的句柄数。
.NET应用程序域
.NET平台下,程序集并没有直接加载进进程中(传统的Win32程序是直接承载的)。.NET可执行程序承载在进程的一个逻辑分区中,术语称应用程序域(简称AppDomain)。一个进程可以拥有多个应用程序域,应用程序域的全部目的就是提供隔离性,相比较与传统的:
1.应用程序域是.NET平台操作系统独立性的关键特性。这种逻辑分区将不同操作系统表现加载可执行程序的差异抽象化了。
2.和一个完整的进程相比,应用程序域的CPU和内存占用要小的多。
3.应用程序域为承载的应用程序提供了深度的隔离。一个失败,其他不会失败。
单个进程可以承载多个应用程序域,每个程序域都和该进程的其他程序域隔离开来,无法相互访问。在线程启动的时候,CLR将自动创建这个特定的应用程序域(默认应用程序域)。然后根据需要创建其他程序域。
对象上下文
应用程序域是承载.NET程序集的进程的逻辑分区。与此相似,应用程序域也可以进一步被划分为多个上下文边界(context boundary)。事实上,.NET上下文为单独的应用程序域提供了一种方式,该方式能为一个给定对象建立“特定的家”(specific home)。
使用上下文,CLR可以确保在运行时有特殊需求的对象,可以通过拦截进出上下文的方法调用,得到适当的和一致的处理。这个拦截层允许CLR调整当前的方法调用,以便满足给定上下文的设定要求。比如,如果定义一个C#类型需要自动线程安全(使用【Synchronization】特性),CLR将会在分配期间创建“上下文同步”。
和一个进程定义了默认的应用程序域一样,每一个应用程序域都有一个默认的上下文(context 0)。大多数.NET对象都会被加载到上下文0中。如果CLR判断一个新创建的对象有特殊需求,一个新的上下文边界将会在承载它的应用程序域中被创建。
1.一个.NET进程可以承载多个应用程序域。每一个应用程序域可以承载多个相关的.NET程序集,并且可以由CLR(或者AppDomain)独立地加载或卸载应用程序域。
2.一个给定的应用程序域中包含一个或多个上下文。使用上下文,CLR能够将“由特殊需求的”对象放置到一个逻辑容器中,确保该对象的运行时需求能够被满足。
程序集
一个.NET应用程序可以由多个程序集拼装而成的。程序集,简单来说,就是一个以公共语言运行库(CLR)为宿主的、版本化的、自描述的二进制文件。尽管显示中.NET程序集和以往Win32二进制文件(包括遗留的COM服务对象)的文件扩展名(*.exe或*.dll)完全相同,但是两者的内部构成几乎完全不同。
程序集可以促进代码重用、确定类型边界、可版本化的单元、自描述的、可配置的。
.NET程序集的格式
n Win32文件首部
Win32文件首部使程序集可以被Windows系列操作系统加载和操作。使用dumpbin.exe结合/headers标记打开一个.NET程序集,可以浏览该程序集的Win32文件首部信息。
n CLR文件首部
为了驻留于CLR中,所有的.NET文件都必须还有CLR首部数据块。它定义了多个标记,它们使得运行库可以了解到托管文件的布局。例如,文件中元数据和资源的位置、程序集构建的运行库版本、公钥值等。使用dumpbin.exe结合/clrheader。
n CIL代码
程序集的核心部分包含CIL代码,这些CIL代码是独立于平台和CPU的中间语言。运行时,程序集内部的CIL代码才被编译成特定平台和CPU的指令。
n 类型元数据
元数据完整的描述了程序集内含另行和引用外部类型的格式。
n 程序集清单
详细记录了程序集中的每一个模块,构建程序集的版本以及该程序集引用的所有外部程序集。
n 可选的嵌入资源
单文件程序集和多文件程序集
程序集由多个模块组成。大多数情况下,程序集只由一个模块组成。这种情况下,(逻辑)程序集和实际的(物理)二进制文件是一一对应的(因此被称为单文件程序集)。多文件程序集市一个.NET*.dll的集合,这些DLL作为单个逻辑单元进行部署和版本化。通常,其中一个会作为主模块,它将包含程序集级别的清单。主模块的清单记录了它依赖的每一个*.dll文件
私有程序集
私有程序集要求放置在客户端应用程序所有在目录(应用程序目录)或者子目录下。
探测过程
.NET运行环境使用一种叫探测(probing)的技术解析私有程序集的位置(这项技术并没有这个名字听起来那样具有侵略性)。
共享程序集
一个共享程序集不在部署使用它的应用程序目录中,它安装在GAC。GAC是Windows下名为Assembly的目录。
强名称
在部署程序集到GAC之前,必须赋予它一个强名称,用于标示给定.NET二进制文件的发行者。它的作用就好比全局唯一标示符(GUID)在COM中的作用。它由一组相关数据组成:
n 程序集的有好名称(程序集名减去文件扩展名)
n 程序集的版本号(使用[AssemblyVersion]特性赋值)
n 公钥值(使用[AssemblyKeyFile]特性赋值)
n 用于本地化得可选的区域性标识(使用[AssemblyCulture]特性赋值)
n 嵌入的数字签名,使用基于程序集内容的散列值和私钥值生成。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tuwen/archive/2010/04/05/5451463.aspx