• 应用程序域 koma


       AppDomain是一组程序集的逻辑容器, AppDomain唯一的作用就是进行隔离, 是.Net中独有的. 创建一个托管应用程序同时会创建一个默认AppDomain

      AppDomain具体功能

        1.一个AppDomain中的代码创建的对象不能由另一个AppDomain中的代码直接访问

            如果需要访问,则需要通过代理的形式, 即使用"按引用封发" 和"按值封发"

        2.  AppDomain可以卸载

               CLR不支持从一个AppDomain卸载程序集,但是可以卸载AppDomain, 卸载AppDomain的同时,AppDomain中分配的所有资源一并释放

        3.  AppDomain可以单独保护

            创建AppDomain的同时,可以分配一个权限

        4.. AppDomain可以单独配置

            在创建AppDomain的同时,亦可以独立设置配置

       创建AppDomain

    //参数说明: 1: 应用程序域名  2: 权限  3:配置   传null则表示按当前AppDomain配置
    AppDomain appDomain = AppDomain.CreateDomain("应用程序域名", null, null);

      跨AppDomain访问对象

        跨AppDomain访问对象有3种行为,  "按引用封送" , "按值封送", "不能封送"

          首先构造3个类,即按 " 按应用封送" , "按值封送", "不能封送" ,注意, 如何封送,或者说能不能封送, 是有这个类型自己决定的

    //按应用封送
    publicclass MarshlaByRefType : MarshalByRefObject
    {
    publicvoid DoSomthing()
    {
    //.....
    }
    }

    //按值封送
    [Serializable]
    publicclass MarshalByValType : Object
    {
    publicvoid DoSomthing()
    {
    //.....
    }
    }

    //不能封送
    publicclass NonMarshalableType : Object
    {
    publicvoid DoSomthing()
    {
    //.....
    }
    }

     调用:

    //通过线程,可以获取当前AppDomain
    AppDomain currAppDomain = System.Threading.Thread.GetDomain();
    //输出当前AppDomain 名称,FriendlyName 是只读的,只有创建是才可以赋值, 默认AppDomain名称为应用程序名
    Console.WriteLine(currAppDomain.FriendlyName);

    //获取当前程序集名称
    string exeAssemble = Assembly.GetEntryAssembly().FullName;

    按引用封送

    //按应用封送
    AppDomain refAppDomain = AppDomain.CreateDomain("RefAddDomain", null, null);
    MarshalByRefType marshalRefType
    = (MarshalByRefType)refAppDomain.CreateInstanceAndUnwrap(exeAssemble, "MarshalByRefType");
    /*
    * 顺利执行
    * 当代码执行到此处时, 线程会切换到refAppDomain的应用程序与中,执行真实的DoSomthring()
    * 此处的refAppDomain 只不过是一个代理引用
    */
    marshalRefType.DoSomthing();
    //调用IsTransparentProxy判断是否为代理 Result: true
    Console.WriteLine("Is Proxy={0}", RemotingServices.IsTransparentProxy(refAppDomain));

    按值封送

    //按值封送
    AppDomain valAppDomain = AppDomain.CreateDomain("RefAddDomain", null, null);
    MarshalByValType marshalValType
    = (MarshalByValType)valAppDomain.CreateInstanceAndUnwrap(exeAssemble, "MarshalByValType");
    /*
    * 顺利执行
    * 代码执行到此处时,实际调用的是当前AppDomain marshalValType的DoSomthing()方法
    * 因为MarshalByValType标记了Serializable特性
    */
    marshalRefType.DoSomthing();
    //调用IsTransparentProxy判断是否为代理 Result: false
    Console.WriteLine("Is Proxy={0}", RemotingServices.IsTransparentProxy(marshalValType));

    不能封送

    //不能封送
    AppDomain nonAppDomain = AppDomain.CreateDomain("RefAddDomain", null, null);
    NonMarshalableType marshalNonType
    = (NonMarshalableType)nonAppDomain.CreateInstanceAndUnwrap(exeAssemble, "NonMarshalableType");
    /*
    * 此处异常
    */
    marshalRefType.DoSomthing();

    监视AppDomain
      设置AppDomain的MonitoringEnabled属性为true, 启用监视.  设置为true后,无法设置为false,即启用监视后不能关闭

      启用监视后, 可以通过下面四个只读属性查看AppDomain运行相关参数

                AppDomain.MonitoringIsEnabled =true;
    //所有AppDomain使用字节数
    AppDomain.MonitoringSurvivedProcessMemorySize;
    //当前正在使用的字节数
    nonAppDomain.MonitoringSurvivedMemorySize;
    //此AppDomain分配的直接数
    nonAppDomain.MonitoringTotalAllocatedMemorySize;
    //CPU占用率
    nonAppDomain.MonitoringTotalProcessorTime;

    AppDomain FirstChance 异常通知

      通过设置FirstChanceException事件 ,可以获取AppDomain异常,但是无法终止,  当AppDomain遇到异常时,会向上查找Catch快,如果没有找到,则会继续向上抛,知道遇到捕获快为止,反之程序异常终止

       注意:

        不同的AppDomain引用System.dll时, 每个AppDomain都会创建的自己的内存区域,也就是说AppDomain之见毫不相干,各干各得, 虽然这是一种浪费,但是为了保证隔离性,这是必须的,   同时卸载AppDomain时,也不会影响其他AppDomain.

  • 相关阅读:
    如何实现ZBrush 4R7中按钮颜色的自定义
    Zbrush遮罩边界该怎么实现羽化和锐化
    怎么在ZBrush中通过遮罩得到子物体
    怎样用好ZBrush中的PaintStop插件
    SQL 如果存在就更新,如果不存在就添加,使用 Merge 函数(SQL2008版本及以上)
    SQL 实现,如果存在就更新,如果不存在就添加
    验证码,字体旋转。
    瀑布流代码,简洁版 带分页
    瀑布流代码,简洁版
    EF
  • 原文地址:https://www.cnblogs.com/yihui/p/2392643.html
Copyright © 2020-2023  润新知