コード例 #1
0
ファイル: Program.cs プロジェクト: frankbsd/CLRViaCSharp
        private static void Marshalling()
        {
            AppDomain adCallingThreadDomain = Thread.GetDomain();

            string callingDomainName = adCallingThreadDomain.FriendlyName;

            Console.WriteLine("Default AppDomain's friendly name={0}", callingDomainName);

            string exeAssembly = Assembly.GetEntryAssembly().FullName;

            Console.WriteLine("Main assembly={0}", exeAssembly);

            AppDomain ad2 = null;

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

            ad2 = AppDomain.CreateDomain("AD #2", null, null);
            MarshalByRefType mbrt = null;

            mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "Chapter22.MarshalByRefType");

            Console.WriteLine("Type={0}", mbrt.GetType().ToString());


            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));

            mbrt.SomeMethod();

            AppDomain.Unload(ad2);

            try
            {
                mbrt.SomeMethod();
                Console.WriteLine("Successful call.");
            }
            catch (AppDomainUnloadedException)
            {
                Console.WriteLine("Failed call.");
            }


            Console.WriteLine("{0}Deomo #2", Environment.NewLine);
            ad2 = AppDomain.CreateDomain("AD #2", null, null);

            mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "Chapter22.MarshalByRefType");

            MarshalByValType mbvt = mbrt.MethodWithReturn();

            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbvt));
            Console.WriteLine("Returned object created " + mbvt.ToString());

            AppDomain.Unload(ad2);

            try
            {
                Console.WriteLine("Returned object created " + mbvt.ToString());
            }
            catch (AppDomainUnloadedException)
            {
                Console.WriteLine("Failed call");
            }



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

            ad2  = AppDomain.CreateDomain("AD #2", null, null);
            mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "Chapter22.MarshalByRefType");


            NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName);

            Console.WriteLine("返回不可封送对象");
        }
コード例 #2
0
        //AppDomain没有在.NET Core当中实现,需要使用.NET Framework
        private static void Marshalling()
        {
            //获取AppDomain引用
            AppDomain adCallingThreadDomain = Thread.GetDomain();

            //每个AppDomain都分配了字符串名称
            string callingDomainName = adCallingThreadDomain.FriendlyName;

            Console.WriteLine("Defaul AppDomain friendly name = {0}", callingDomainName);

            //获取包含了Main的方法集
            string exeAssembly = Assembly.GetEntryAssembly().FullName;

            Console.WriteLine("Main assembly={0}", exeAssembly);

            AppDomain ad2 = null;

            //使用Marshal-by-Reference进行通信
            Console.WriteLine("{0} Demo #1", Environment.NewLine);

            //新建一个AppDomain,从当前的继承安全性和配置
            ad2 = AppDomain.CreateDomain("AD #2", null, null);
            MarshalByRefType mbrt = null;

            //将程序集加载到新的AppDomain当中,构造一个对象,把他封装会原来的AppDomain(实际会得到到一个代理引用)
            mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");
            Console.WriteLine("Type={0}", mbrt.GetType()); //CLR在类型上撒谎了
            //证明得到的是一个代理对象的引用
            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));

            //看起来像是再MarshalByRefType上调用方法
            //实际是在代理类型上调用方法
            mbrt.SomeMethod();

            //卸载
            AppDomain.Unload(ad2);

            //mbrt引用一个有效的代理对象,代理对象引用一个无效的AppDomain
            try
            {
                mbrt.SomeMethod();
                Console.WriteLine("Successful calling");
            }
            catch (AppDomainUnloadedException)
            {
                Console.WriteLine("Failed call");
            }


            //DEMO2: 使用Marshal-by-value进行跨AppDomain通信
            Console.WriteLine("{0} Demo #2", Environment.NewLine);

            ad2  = AppDomain.CreateDomain("AD #2", null, null);
            mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");
            //对象的方法返回对象的副本,按值封送
            MarshalByValType mbvt = mbrt.MethodWithReturn();

            //证明得到的不是一个代理对象的引用
            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));
            Console.WriteLine("Returned object created ", mbvt.ToString());
            //卸载
            AppDomain.Unload(ad2);
            //mbvt是值,卸载AppDomain没有影响
            try
            {
                mbrt.SomeMethod();
                Console.WriteLine("Successful calling");
            }
            catch (AppDomainUnloadedException)
            {
                Console.WriteLine("Failed call");
            }

            //Demo 3: 使用不可封送的类型跨AppDomain通信
            ad2  = AppDomain.CreateDomain("AD #2", null, null);
            mbrt = (MarshalByRefType)ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");
            //对象的方法返回一个不可封送的对象,抛出异常
            NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName);
        }