.Net AppDomain详解(二)
AppDomain 类
表示应用程序域,它是一个应用程序在其中执行的独立环境。 此类不能被继承。
命名空间: System
程序集: mscorlib(位于 mscorlib.dll)
System.MarshalByRefObject
System.AppDomain
[ClassInterfaceAttribute(ClassInterfaceType.None)] [ComVisibleAttribute(true)] public sealed class AppDomain : MarshalByRefObject, _AppDomain, IEvidenceFactory
名称 | 说明 |
---|---|
ActivationContext |
获取当前应用程序域的激活上下文。 |
ApplicationIdentity |
获得应用程序域中的应用程序标识。 |
ApplicationTrust |
获取说明授予应用程序的权限以及应用程序是否拥有允许其运行的信任级别的信息。 |
BaseDirectory |
获取基目录,它由程序集冲突解决程序用来探测程序集。 |
CurrentDomain |
获取当前 Thread 的当前应用程序域。 |
DomainManager |
获得初始化应用程序域时主机提供的域管理器。 |
DynamicDirectory |
获取目录,它由程序集冲突解决程序用来探测动态创建的程序集。 |
Evidence |
获取与该应用程序域关联的 Evidence。 |
FriendlyName |
获取此应用程序域的友好名称。 |
Id |
获得一个整数,该整数唯一标识进程中的应用程序域。 |
IsFullyTrusted |
获取一个值,该值指示加载到当前应用程序域的程序集是否是以完全信任方式执行的。 |
IsHomogenous |
获取一个值,该值指示当前应用程序域是否拥有一个为加载到该应用程序域的所有程序集授予的权限集。 |
MonitoringIsEnabled |
获取或设置一个值,该值指示是否对当前进程启用应用程序域的 CPU 和内存监视。 一旦对进程启用了监视,则无法将其禁用。 |
MonitoringSurvivedMemorySize |
获取上次回收后保留下来的,已知由当前应用程序域引用的字节数。 |
MonitoringSurvivedProcessMemorySize |
获取进程中所有应用程序域的上次回收后保留下来的总字节数。 |
MonitoringTotalAllocatedMemorySize |
获取自从创建应用程序域后由应用程序域进行的所有内存分配的总大小(以字节为单位,不扣除已回收的内存)。 |
MonitoringTotalProcessorTime |
获取自从进程启动后所有线程在当前应用程序域中执行时所使用的总处理器时间。 |
PermissionSet |
获取沙盒应用程序域的权限集。 |
RelativeSearchPath |
获取基目录下的路径,在此程序集冲突解决程序应探测专用程序集。 |
SetupInformation |
获取此实例的应用程序域配置信息。 |
ShadowCopyFiles |
获取应用程序域是否配置为影像副本文件的指示。 |
名称 | 说明 |
---|---|
AssemblyLoad |
在加载程序集时发生。 |
AssemblyResolve |
在对程序集的解析失败时发生。 |
DomainUnload |
在即将卸载 AppDomain 时发生。 |
FirstChanceException |
当托管代码抛出异常时发生,在运行时在调用堆栈中搜索应用程序域中的异常处理程序之前。 |
ProcessExit |
当默认应用程序域的父进程退出时发生。 |
ReflectionOnlyAssemblyResolve |
当程序集的解析在仅限反射的上下文中失败时发生。 |
ResourceResolve |
当资源解析因资源不是程序集中的有效链接资源或嵌入资源而失败时发生。 |
TypeResolve |
在对类型的解析失败时发生。 |
UnhandledException |
当某个异常未被捕获时出现。 |
应用程序域,由表示AppDomain对象,帮助提供有关执行托管的代码的隔离、 卸载和安全边界。
-
使用应用程序域隔离可能会终止进程的任务。 如果状态AppDomain,正在执行的任务变得不稳定,AppDomain可以而不会影响进程中卸载。 进程必须运行很长一段无需重新启动时,这很重要。 你还可以使用应用程序域隔离不应共享数据的任务。
-
如果程序集被加载到默认应用程序域,它无法从内存中卸载过程运行时。 但是,如果您打开第二个应用程序域加载和执行程序集,程序集是卸载卸载该应用程序域时。 使用此方法最大程度减少偶尔使用大型 Dll 的长时间运行进程的工作集。
多个应用程序域可以运行在一个进程中;但是,没有应用程序域和线程之间的一对一的相关性。 多个线程可以属于单个应用程序域,并且单个应用程序域中时的给定的线程并不局限于单个应用程序域,在任何给定时间,执行线程。
使用创建应用程序域CreateDomain方法。 AppDomain实例用于加载和执行程序集 (Assembly)。 当AppDomain是不再在使用中,可以将它卸载。
AppDomain类实现的一组启用应用程序进行响应时加载的程序集,应用程序域将被卸载,或引发未经处理的异常时的事件。
有关使用应用程序域的详细信息,请参阅应用程序域。
此类实现MarshalByRefObject, _AppDomain,和IEvidenceFactory接口。
决不要创建的远程操作包装AppDomain对象。 这样可以将发布到的远程引用AppDomain,如公开方法CreateInstance与远程访问和有效地销毁该的代码访问安全性AppDomain。 恶意客户端连接到远程AppDomain无法获取任何资源的访问权限AppDomain本身具有访问权限。 不创建任何扩展的类型的远程操作包装MarshalByRefObject并实现恶意客户端无法用于绕过安全系统的方法。
小心 |
---|
默认值为AppDomainSetup.DisallowCodeDownload属性是false。 此设置是不安全的服务。 若要防止服务下载部分受信任的代码,请将此属性设置为true。 |
此示例演示如何创建一个新AppDomain,新实例化中的一个类型AppDomain,以及与该类型的对象通信。 此外,此示例演示如何卸载AppDomain导致要进行垃圾回收的对象。
using System; using System.Reflection; using System.Threading; class Module1 { public static void Main() { // Get and display the friendly name of the default AppDomain. string callingDomainName = Thread.GetDomain().FriendlyName; Console.WriteLine(callingDomainName); // Get and display the full name of the EXE assembly. string exeAssembly = Assembly.GetEntryAssembly().FullName; Console.WriteLine(exeAssembly); // Construct and initialize settings for a second AppDomain. AppDomainSetup ads = new AppDomainSetup(); ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; ads.DisallowBindingRedirects = false; ads.DisallowCodeDownload = true; ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; // Create the second AppDomain. AppDomain ad2 = AppDomain.CreateDomain("AD #2", null, ads); // Create an instance of MarshalbyRefType in the second AppDomain. // A proxy to the object is returned. MarshalByRefType mbrt = (MarshalByRefType) ad2.CreateInstanceAndUnwrap( exeAssembly, typeof(MarshalByRefType).FullName ); // Call a method on the object via the proxy, passing the // default AppDomain's friendly name in as a parameter. mbrt.SomeMethod(callingDomainName); // Unload the second AppDomain. This deletes its object and // invalidates the proxy object. AppDomain.Unload(ad2); try { // Call the method again. Note that this time it fails // because the second AppDomain was unloaded. mbrt.SomeMethod(callingDomainName); Console.WriteLine("Sucessful call."); } catch(AppDomainUnloadedException) { Console.WriteLine("Failed call; this is expected."); } } } // Because this class is derived from MarshalByRefObject, a proxy // to a MarshalByRefType object can be returned across an AppDomain // boundary. public class MarshalByRefType : MarshalByRefObject { // Call this method via a proxy. public void SomeMethod(string callingDomainName) { // Get this AppDomain's settings and display some of them. AppDomainSetup ads = AppDomain.CurrentDomain.SetupInformation; Console.WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}", ads.ApplicationName, ads.ApplicationBase, ads.ConfigurationFile ); // Display the name of the calling AppDomain and the name // of the second domain. // NOTE: The application's thread has transitioned between // AppDomains. Console.WriteLine("Calling from '{0}' to '{1}'.", callingDomainName, Thread.GetDomain().FriendlyName ); } } /* This code produces output similar to the following: AppDomainX.exe AppDomainX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null AppName=, AppBase=C:\AppDomain\bin, ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config Calling from 'AppDomainX.exe' to 'AD #2'. Failed call; this is expected. */
此类型的所有公共静态(Visual Basic 中的 已共享 在 Visual Basic 中)成员都是线程安全的。不保证所有实例成员都是线程安全的。