跨AppDomain边界访问对象

本文代码来源:CLR via C# 4,22章。大家不用手敲,复制粘贴就能看到效果

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

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            //获取AppDomain引用(当前线程的AppDomain)
            AppDomain adCalllingThreadDomain = Thread.GetDomain();
            //分配友好字符串名称
            string clallingDomainName = adCalllingThreadDomain.FriendlyName;
            Console.WriteLine("Default AppDomain name={0}", clallingDomainName);
            string exeAssembly = Assembly.GetEntryAssembly().FullName;
            Console.WriteLine("Main assembly name= {0}", exeAssembly);
            //定义局部变量引用AppDomain
            AppDomain ad2 = null;
            //***DEMO1:使用Marshal-by-Reference进行跨域通讯***
            Console.WriteLine("{0} Demo  #1", Environment.NewLine);
            //新建AppDomain(从当前AppDomain继承安全性和配置)
            ad2 = AppDomain.CreateDomain("AD #2", null, null);
            MarshalByRefType mbrt = null;
            mbrt = null;
            //将我们的程序集加载到新的AppDomain中,构造一个对象,把它封送回我们的AppDomain(实际得到对一个代理的引用)
            mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "ConsoleApplication4.MarshalByRefType");
            Console.WriteLine("Type={0}", mbrt.GetType());//CLR在类型上撒谎了。
            Console.WriteLine("is Proxy= {0}", RemotingServices.IsTransparentProxy(mbrt));
            mbrt.SomeMethod();
            //卸载AppDomain
            AppDomain.Unload(ad2);
            try
            {
                mbrt.SomeMethod();
                Console.WriteLine("Successful call.");
            }
            catch (AppDomainUnloadedException)
            {

                Console.WriteLine("Faiiled call");
            }
            //*** DEMO2 : 使用Marshal-by-Value进行跨AppDomain 通信 ***
            Console.WriteLine("{0} Demo #2", Environment.NewLine);
            //新建一个AppDomain(从当前AppDomain继承安全性和配置)
            ad2 = AppDomain.CreateDomain("AD #2", null, null);
            mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "ConsoleApplication4.MarshalByRefType");
            //对象的方法返回对象的副本;
            //对象按值(而非按引用)封送
            MarshalByValType mbvt = mbrt.MethodWithReturn();
            Console.WriteLine("is proxy={0}", RemotingServices.IsTransparentProxy(mbvt));
            Console.WriteLine("Return object created " + mbvt.ToString());
            AppDomain.Unload(ad2);
            try
            {
                Console.WriteLine("Return object created " + mbvt.ToString());
                Console.WriteLine("Successful call.");
            }
            catch (AppDomainUnloadedException)
            {

                Console.WriteLine("Faiiled call");
            }
            //*** DEMO3 : 使用不可封送的类型进行跨AppDomain通信**
            Console.WriteLine("{0} Demo #3", Environment.NewLine);
            ad2 = AppDomain.CreateDomain("AD #2", null, null);
            mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "ConsoleApplication4.MarshalByRefType");
            NonMarshalableType nmt = mbrt.MethodArgAndReturn(clallingDomainName);//异常:NonMarshalableType 未序列化
            Console.ReadKey();

        }

    }
    //该类的实例可跨越AppDomain的边界“按引用封送”
    public sealed class MarshalByRefType : MarshalByRefObject
    {
        public MarshalByRefType()
        {
            Console.WriteLine("{0} ctor running in {1}", this.GetType(), Thread.GetDomain().FriendlyName);
        }

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

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

        public NonMarshalableType MethodArgAndReturn(string callingDomainName)
        {
            Console.WriteLine("Execting in {0} ---- {1} " ,Thread.GetDomain().FriendlyName , callingDomainName);
            NonMarshalableType t = new NonMarshalableType();
            return t;
        }


    }
    //该类的实例可以跨越AppDomain边界“按值封送”
    [Serializable]
    public sealed class MarshalByValType : Object
    {
        private DateTime m_creationTime = DateTime.Now; //注意:DateTime 是可序列化的。

        public MarshalByValType()
        {
            Console.WriteLine("{0} ctor running in {1},create on {2:D}", this.GetType().ToString(), Thread.GetDomain().FriendlyName, m_creationTime);
        }

        public override string ToString()
        {
            Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName);
            return m_creationTime.ToLongDateString();
        }
    }
    //该类不能跨AppDomain边界封送

    public sealed class NonMarshalableType : Object
    {
        public NonMarshalableType()
        {
            Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName);
        }
    }


}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值