应用程序域进一步认识

新知识点:跨域

  • 一个AppDomain中建立的对象不能由另外一个AppDomain的代码进行访问,必须进行特殊的声明,使用特殊的跨域调用;
  • AppDomain 能够单独配置;
  • 每一个AppDomain都有本身的Loader堆,记录自AppDomain建立以来,访问过哪些类型,每一个类型对象都有一个方法表,指向JIT编译的本地代码;

运行示例:dom

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Runtime.Remoting;

namespace FactoryMode
{
    [Serializable]
    public class Program : MarshalByRefObject
    {
        //在调用此方法时,观察"调用堆栈",发现一次"外部代码"的切换,代表自进行了一次跨域操做
        public void NotMainMethod()
        {
            //AppDomain.CurrentDomain 能够获得一样的结果
            var curCallingDomain = Thread.GetDomain(); 

            var curCallingDomainName = curCallingDomain.FriendlyName;
            Console.WriteLine("Cross-domain calling, curdomain name={0}.", curCallingDomainName);
        }

        static void Main(string[] args)
        {
            var curCallingDomain = Thread.GetDomain();

            var curCallingDomainName = curCallingDomain.FriendlyName;
            Console.WriteLine("Default AppDomain's friendly name={0}.", curCallingDomainName);

            string exeAssembly = Assembly.GetExecutingAssembly().CodeBase;
            Console.WriteLine("Main assembly={0}.", exeAssembly);

            AppDomain otherDomain = null;
            Console.WriteLine("{0}Demo #1", Environment.NewLine);

            otherDomain = AppDomain.CreateDomain("AD #2", null, null);
            //在"AD#2"应用程序域中建立 Programs 对象,并向默认应用程序域返回它的引用;
            var mbrt = (Program)otherDomain.CreateInstanceFromAndUnwrap(exeAssembly, "FactoryMode.Program");
            Console.WriteLine("Type={0}", mbrt.GetType());
            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));

            //利用引用调用方法,方法中的打印显示出此时线程正运行在"AD#2"应用程序域中
            mbrt.NotMainMethod();
           
            Console.Read();

        }
    }
}
  • 进行跨域封送,必须支持序列化;
  • 例子展现了跨域的引用传递,另外还有值传递;
  • AppDomain 的构造 AppDomainSetup 参数决定了是否使用单独的配置;

  备注:性能

  • 获取程序集的路径名,是用 CodeBase 字段 - -;
  • 要得到主程序集引用的其余程序集,能够经过对统一路径下dll的加载来完成,并不须要反射什么的其余手段;

卸载AppDomain:spa

  • 挂机进程中执行过托管代码的全部线程;
  • 检查正在该AppDomain上运行的线程,与会返还到该AppDomain上运行的线程;
  • 抛出 ThreadAbortException,执行全部 finally 块中的内容进行资源清理;
  • 在公共堆中遍历已卸载AppDomain中的对象,进行标记后进行垃圾回收;
  • 恢复剩余全部线程的执行;

监视AppDomain:线程

  很是好用的功能,能够用来作资源监控,性能监测;code

  • MonitoringSurvivedProcessMemorySize: 静态属性,当前 CLR 控制的全部 AppDomain 正在使用的字节数;
  • MonitoringTotalAllocatedMemorySize: 实例属性,返回特定的 AppDomain 已分配的字节数;
  • MonitoringSurvivedMemorySize: 实例属性,返回特定的 AppDomain 正在使用的字节数;
  • MonitoringTotalProcessorTime: 实例属性,返还特定的 AppDomain 的CPU占用率;
相关文章
相关标签/搜索