动态创建AppDomain一

demo来源:https://msdn.microsoft.com/en-us/w124b5fa

/***
AppDomain 表示应用程序域,它是一个应用程序在其中执行的独立环境。无法继承此类。

    应用程序域(由 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;

namespace ConsoleApplication1
{
    //ref:https://msdn.microsoft.com/en-us/w124b5fa

    class Program
    {
        static void Main(string[] args)
        {
            // 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);

            AppDomainSetup ads = new AppDomainSetup();
            ads.ApplicationBase = Environment.CurrentDirectory;
            ads.DisallowCodeDownload = true; //防止服务下载部分受信任的代码,请将此属性设置为 trues
            ads.DisallowBindingRedirects = false;
            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.");
            }

            Console.ReadKey();
        }
    }

    // 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
            );
        }
    }
}


参考:http://www.cnblogs.com/rinack/p/5832800.html

相关阅读:

System Namespace
How to: Configure an Application Domain
How to: Create an Application Domain
How to: Load Assemblies into an Application Domain
How to: Unload an Application Domain



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值