应用程序域

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

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Marshalling();
        }

        static void Marshalling()
        {
            //获得当前线程的应用程序域
            AppDomain callThreadDomin = Thread.GetDomain();

           
            //获取当前应用程序域的友好名字
            string DomainName = callThreadDomin.FriendlyName;
            Console.WriteLine("Domain name is :{0}",DomainName);

            //获取当前程序集的入口点全名
            String exeAssembly = Assembly.GetEntryAssembly().FullName;
            Console.WriteLine("当前程序集的入口点是:{0}",exeAssembly);


            //在线程栈上声明一个变量没有指向托管堆上任何变量

            AppDomain ad2 = null;

            // 跨应用程序使用引用封送

            //Environment 类封装了关于当前环境和运行平台信息的相关信息
            Console.WriteLine("{0} Demo #1",Environment.NewLine);

            Console.WriteLine("********************");

            // 创建一个新的应用程序域

            ad2 = AppDomain.CreateDomain("AD #2 ", null, null);
            MarshaByRefType mbr = null;

            //创建指定类型的新实例. 形参指定定义类型的程序集以及类型的名称
            //其实该实例是Ad #2 应用程序域中 MarshalByRefType 类型的一个代理
            //通俗的理解就是绑定应用程序域
            mbr = (MarshaByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, typeof(MarshaByRefType).FullName);

            Console.WriteLine("Type={0}",mbr.GetType());   //CLR 在类型撒谎
            Console.WriteLine("-------");

            // 检查该类型是不是一个真正的代理对象

            Console.WriteLine("IS proxy={0}",RemotingServices.IsTransparentProxy(mbr));

            //Console.ReadLine();


            // 看起来像是在 MarshalByRefType 上调用一个方法,实则不然  我们是在代理类型上调用一个方法 代理使 线程转至拥有对象的 那个AppDomain 并在真实的对象调用这个方法
            mbr.SomeMethod();

            AppDomain.Unload(ad2);
            // 此时mbr 引用一个有效的代理对象,代理对象引用一个无效的Appdomin
            try
            {
                mbr.SomeMethod();
            }
            catch(AppDomainUnloadedException e)
            {
                //throw e;
                Console.WriteLine("Failed call");
            }

            //Demo2 : 跨应用程序域使用按值封送

            Console.WriteLine("{0}Demo #2", Environment.NewLine);

            ad2 = AppDomain.CreateDomain("AD #2", null, null);
            mbr = (MarshaByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, typeof(MarshaByRefType).FullName);

            // 对象的方法返回所返回对象一个副本   对象按值封送

            MarshalByValType mbrv = mbr.MethodWithReturn();
            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrv));

            // 此时实际上我们是在真正的 MarshalByValType 对象上调用方法
            Console.WriteLine("Returned object created " + mbrv.ToString());

            AppDomain.Unload(ad2);
            try
            {
                Console.WriteLine("Returned object created " + mbrv.ToString());
                Console.WriteLine("Seccessful call");
            }
            catch(AppDomainUnloadedException)
            {
                Console.WriteLine("Failed call");
            }

        }


        //此类继承 MarshalByRefObject 跨应用程序域使用引用封送
        public sealed class MarshaByRefType:MarshalByRefObject
        {

            // 构造函数显示当前应用程序域
            public MarshaByRefType()
            {
                Console.WriteLine("{0} ctor running in {1}",this.GetType().ToString(),Thread.GetDomain().FriendlyName);
                Console.WriteLine("-----------");
            }

            public void SomeMethod()
            {
                Console.WriteLine("Executing " +Thread.GetDomain().FriendlyName);
            }

            public MarshalByValType MethodWithReturn()
            {
                Console.WriteLine("Executing is "+Thread.GetDomain().FriendlyName);
                MarshalByValType t = new MarshalByValType();
                return t;
            }
        }


        [Serializable]  // 指示该类可以被序列化
        public sealed class MarshalByValType : Object
        {
            private DateTime m_creattionTime = DateTime.Now;
            public MarshalByValType()
            {
                Console.WriteLine("{0} ctor running is in{1},Ceated on {2:D}",this.GetType().ToString (),Thread.GetDomain().FriendlyName,m_creattionTime);
            }

            public override string ToString()
            {
                return m_creattionTime.ToLongDateString();
            }
        }


        //既不继承MarshalByRefObject 也不能序列化
        public sealed class NonMarshalableType : Object
        {
            public NonMarshalableType()
            {
                Console.WriteLine("Executing in "+Thread.GetDomain().FriendlyName);
            }
        }
    }
}

posted @ 2012-05-09 11:18  至道中和  阅读(173)  评论(0编辑  收藏  举报