应用程序域基础

简介:

应用程序域基础

们都知道,进程是操作系统进行资源调度和分配基本单位,每个进程实际代表当前应用程序从启动到结束全部过程。对于Windows每一个.exe文件,在运行时都要由一个进程来承载它。与非托管.exe文件不同是,托管.exe文件并没有直接将程序集加载到当前进程当中,而是将程序集加载到应用程序域中,然后将应用程序域加载到进程中。每个进程可以承载多个应用程序域。因此,对于托管程序,每个进程可以承载多个应用程序,这同时也提升应用程序性能,因为进程切换所耗费性能要多于应用程序域切换。

 

 

 

1.1 应用程序域的特点

托管程序为什么要使用应用程序域呢?概括其优点如下:

1.        在一个应用程序中出现错误不会影响其应用程序。

2.        因为类型安全代码不会导致内存错误,所以使用应用程序域可以确保在一个域中运行代码不会影响进程中应用程序。

3.        能够在不停止整个进程情况下停止单个应用程序。

4.        使用应用程序域时,可以卸载在单个应用程序中运行代码。

5.        在一个应用程序中运行代码不能直接访问其应用程序中代码或资源。

强制实施此隔离,公共语言运行库禁止在不同应用程序域中对象之间进行直接调用。要在各域之间传递对象,可以通过复制这些对象,或通过代理访问这些对象。如果复制对象,那么对该对象调用为本地调用。也就是说,调用方和被引用对象位于同一应用程序域中。如果通过代理访问对象,那么对该对象调用为远程调用。在此情况下,调用方和被引用对象位于不同应用程序域中。域间调用所采用远程调用基础结构与两个进程间调用或两台计算机间调用基础结构相同。因此,被引用对象元数据必须对于两个应用程序域均可用,以便用 JIT正确编译该方法调用。如果调用域对被调用对象元数据没有访问权,则编译可能失败,并引发类型为System.IO.FileNotFound 异常。

1.        代码行为作用范围由它运行所在应用程序决定。

换言之,应用程序域将提供应用程序版本策略等配置设置、它所访问任意远程程序集位置,以及加载到该域中程序集位置信息。

2.        向代码授予权限可以由代码运行所在应用程序域来控制。

1.2 创建应用程序域

.NET提供相关类和方法来获取当前应用程序域基本信息,也提供创建和配置应用程序域成员。其中,AppDomain 类是应用程序域编程接口,此类包括各种方法,这些方法可以创建和卸载域、创建域中各类型实例以及注册各种通知(如应用程序域卸载)。对于应用程序域卸载,将在第3.1.3节做介绍。

 

代码清单1-1演示如何创建一个应用程序域。

代码清单1-1 创建应用程序域

class Program

    {

 

        static void Main(string[] args)

 

        {

 

           AppDomain myDomain=AppDomain.CreateDomain("xuanhunDomain");//创建名为xuanhunDomain应用程序域

           Console.WriteLine("myDomain name is :{0}",myDomain.FriendlyName);//输出创建程序域名称

           Console.WriteLine("当前程序域名称是:{0}",AppDomain.CurrentDomain.FriendlyName);//输出当前程序域名称

           Console.ReadKey();

 

        }

 

    }

 

输出结果如图1-1所示。

image

1-1 输出应用程序域名称

 

1.3 卸载应用程序域

当完成使用应用程序域时,可使用System.AppDomain.Unload方法将其卸载。Unload 方法会正常关闭指定应用程序域。卸载过程中,没有新线程可以访问该应用程序域,并且会释放该应用程序域特定所有数据结构。加载到应用程序域中所有程序集都会被移除,无法再使用。如果应用程序域中程序集不是特定于域,则程序集数据会保留在内存中,直到整个进程关闭。除关闭整个进程,没有机制可以卸载非特定于域程序集。在某些情况下,卸载应用程序域请求不起作用,并导致CannotUnloadAppDomainException。代码清单1-2在代码清单1-1基础上添加卸载xuanhunDomain程序域语句,并且在卸载后再次尝试输出该应用程序域名称,这将引发CannotUnloadAppDomainException

代码清单1-2 卸载应用程序域

class Program

    {

 

        static void Main(string[] args)

 

        {

 

           AppDomain myDomain= AppDomain.CreateDomain("xuanhunDomain");

 

           Console.WriteLine("myDomain name is :{0}",myDomain.FriendlyName);

 

           Console.WriteLine("当前程序域名称是:{0}",AppDomain.CurrentDomain.FriendlyName);

 

           AppDomain.Unload(myDomain);

 

           try//试图访问被卸载应用程序域

           {

 

               Console.WriteLine("myDomain name is :{0}", myDomain.FriendlyName);

 

           }

 

           catch (CannotUnloadAppDomainExceptione)

 

           {

 

               Console.WriteLine(e.Message);

 

           }

 

           Console.ReadKey();

 

}

 

输出结果如图1-2所示。

image

1-2 卸载应用程序域

 

将程序集加载到应用程序域方法已经在第2章中做介绍,这里就不再重复。下面接着讨论如何获得当前线程应用程序域相关信息,如代码清单1-3所示。

代码清单1-3 获得当前线程应用程序域相关信息

public void GetDomainInfo()

 

        {

 

            ActivationContext tContext = AppDomain.CurrentDomain.ActivationContext;//获取上下文信息

       ApplicationIdentity tIdentity=AppDomain.CurrentDomain.ApplicationIdentity;//获取应用程序标识

         

 

            System.Security.Policy.ApplicationTrust tTrust = AppDomain.CurrentDomain.ApplicationTrust;//获取当前程序信任级别

            string tDirectory = AppDomain.CurrentDomain.BaseDirectory;// 获取基目录,它由程序集冲突解决程序用来探测程序集

            AppDomainManager tDomainManager = AppDomain.CurrentDomain.DomainManager;//获得初始化应用程序域时主机提供域管理器

            string tDynamicDirectory = AppDomain.CurrentDomain.DynamicDirectory;//获取目录,它由程序集冲突解决程序用来探测动态创建程序集

            System.Security.Policy.Evidence tEvidence = AppDomain.CurrentDomain.Evidence;//获取与此应用程序域相关联 Evidence,它用做安全策略输入

            string tFrindlyName = AppDomain.CurrentDomain.FriendlyName;//获取此应用程序域友好名称

            int tId = AppDomain.CurrentDomain.Id;//获得一个整数,该整数唯一标识进程中应用程序域

            bool tIsFullTrusted = AppDomain.CurrentDomain.IsFullyTrusted;//表示当前应用程序域中程序集是否为完全信任级别

            bool tIsHomogenous = AppDomain.CurrentDomain.IsHomogenous;//获取一个值表示是否拥有对加载到当前应用程序域所有程序集权限集合

            long tMSMemorySize = AppDomain.CurrentDomain.MonitoringSurvivedMemorySize;

 

            long tMTAMemorySieze = AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize;

 

            TimeSpan tMTPTime = AppDomain.CurrentDomain.MonitoringTotalProcessorTime;

 

            System.Security.PermissionSet tPermissionSet = AppDomain.CurrentDomain.PermissionSet;//获取权限集

            string tRPath = AppDomain.CurrentDomain.RelativeSearchPath;//获取相对于基目录路径,在此程序集冲突解决程序应探测专用程序集

            AppDomainSetup tASetup = AppDomain.CurrentDomain.SetupInformation;//安装信息

            bool tSCopyFiles = AppDomain.CurrentDomain.ShadowCopyFiles;//获取一个指示值,它表明加载到应用程序域中所有程序集是否为影像复制

}

 

在代码清单1-3中,使用AppDomain.CurrentDomain的属性来获取当前应用程序域的实例,可以从中获取当前应用程序域的相关信息,其中.NET 4.0中新增的属性如下:

q  AppDomain.CurrentDomain.MonitoringSurvivedMemorySize。获取上次完全阻止回收后保留下来的、已知由当前应用程序域引用的字节数。

q  AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize。获取自从创建应用程序域后由应用程序域进行的所有内存分配的总大小(以字节为单位,不扣除已回收的内存)。

q  AppDomain.CurrentDomain.MonitoringTotalProcessorTime。获取自从进程启动后所有线程在当前应用程序域中执行时所使用的总处理器时间。

q  AppDomain.CurrentDomain.PermissionSet。获取沙箱应用程序域的权限集。

----------------注,本文部分内容改编自《.NET 安全揭秘》


本文转自悬魂博客园博客,原文链接:http://www.cnblogs.com/xuanhun/archive/2012/06/23/2559264.html,如需转载请自行联系原作者

相关文章
|
Unix C++
在VS2019中CMake生成出现报错
在VS2019中CMake生成出现报错
1885 0
在VS2019中CMake生成出现报错
|
存储 前端开发 Java
Element el-upload 文件上传/图片上传/拖拽上传/附带参数/附带请求头部详解
文目录 1. 前言 2. 基本用法 2.1 前端部分 2.2 后端部分 2.3 获取后端返回信息 3. 外观功能介绍 3.1 拖拽上传 3.2 显示图片 3.3 设置文件列表样式 3.4 显示提示信息 4. 事件功能介绍 4.1 限制上传文件数量 4.2 限制上传文件类型和大小 4.3 移除文件处理 4.4 手动上传 5. 附带参数 6. 附带请求头部 7. 小结
7946 0
|
JavaScript 前端开发 关系型数据库
事件管理工具:用Python和Vue打造在线预订和票务系统
【4月更文挑战第11天】构建一个在线预订和票务系统,结合Python(Flask或Django)后端与Vue.js前端。准备工作包括设置Python环境、Node.js、数据库和Git。后端创建RESTful API,Flask适合轻量级,Django提供完整框架。前端使用Vue CLI、Vuex和Vue Router构建用户界面。通过Vuex管理状态,Vue Router定义路由,Axios与后端通信。这种架构支持团队协作,代码维护和扩展。
268 0
|
开发框架 Linux C++
Qt:强大的跨平台C++应用程序开发框架
Qt:强大的跨平台C++应用程序开发框架
591 3
|
开发框架 JavaScript 前端开发
Electron技术深度解析:构建跨平台桌面应用的利器
【10月更文挑战第13天】Electron技术深度解析:构建跨平台桌面应用的利器
965 0
|
人工智能 算法 JavaScript
无界 SaaS AI 生态大模型:技术在中国,链接全世界
无界 SaaS AI 生态大模型涵盖前端用户界面、后端服务器逻辑、数据库设计、API 接口开发及区块链技术应用。本文提供一个简化框架,介绍技术栈选择、核心功能模块(用户管理、商城、数据确权、链接力、算力算法、AI 生态大模型、全球化支持)及后端示例代码,帮助将商业模式转化为代码。
|
传感器 数据格式
STM32外设系列—DHT11
本文详细介绍了什么是DHT11,介绍了DHT11使用的单总线通信,并详细分析了与DHT11进行数据交互时的时序图。此外,给出了DHT11初始化,接收温湿度信息并校验的程序设计。
867 0
STM32外设系列—DHT11
|
传感器
imx6ull开发板i2c应用编程读取AP3216c传感器数据
imx6ull开发板i2c应用编程读取AP3216c传感器数据
344 0
|
运维 Serverless 云计算
飞天技术观|云上开发新范式:Serverless的必然与应然
在2022年云栖大会上宣布核心产品全面Serverless化之前,阿里云在Serverless领域布局已经有六七年积累了,一直在打磨产品,夯实基础;从去年开始,阿里云进入到了Serverless的第二阶段,一路突飞猛进,相对应地,阿里云Serverless产品数量和丰富度都在快速增长,业务规模也在快速增长。
973 1
|
C++ Windows
[√]window下子线程CCLOG导致主线程阻塞问题
[√]window下子线程CCLOG导致主线程阻塞问题
598 0