예제 #1
0
    public NonMarshalableType MethodArgAndReturn(String callingDomainName)
    {
        // NOTE: callingDomainName is [Serializable]
        Console.WriteLine("Calling from '{0}' to '{1}'.",
                          callingDomainName, Thread.GetDomain().FriendlyName);
        NonMarshalableType t = new NonMarshalableType();

        return(t);
    }
예제 #2
0
            public NonMarshalableType MethodArgAndReturn(string callingDomainName)
            {
                // 注意:callingDomainName 是可序列化的
                Console.WriteLine("Calling from '{0}' to '{1}'.",
                                  callingDomainName, Thread.GetDomain().FriendlyName);
                NonMarshalableType t = new NonMarshalableType();

                return(t);
            }
예제 #3
0
 public NonMarshalableType MethodArgAndReturn(String callingDomainName)
 {
     // NOTE: callingDomainName is [Serializable]
     Console.WriteLine("Calling from ‘{0}’ to ‘{1}’.",
     callingDomainName, Thread.GetDomain().FriendlyName);
     NonMarshalableType t = new NonMarshalableType();
     return t;
 }
예제 #4
0
    private static void Marshalling()
    {
        //获取当前线程在那个AppDomain,效果相同
        var xad  = Thread.GetDomain();
        var xad2 = System.AppDomain.CurrentDomain;


        // Get a reference to the AppDomain that that calling thread is executing in
        AppDomain adCallingThreadDomain = Thread.GetDomain();

        // Every AppDomain is assigned a friendly string name (helpful for debugging)
        // Get this AppDomain's friendly string name and display it
        String callingDomainName = adCallingThreadDomain.FriendlyName;

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

        // Get & display the assembly in our AppDomain that contains the 'Main' method
        String exeAssembly = Assembly.GetEntryAssembly().FullName;

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

        // Define a local variable that can refer to an AppDomain
        AppDomain ad2 = null;

        // *** DEMO 1: Cross-AppDomain Communication using Marshal-by-Reference
        #region demo1
        Console.WriteLine("{0}Demo #1", Environment.NewLine);

        // Create new AppDomain (security & configuration match current AppDomain)
        ad2 = AppDomain.CreateDomain("AD #2", null, null);
        MarshalByRefType mbrt = null;

        // Load our assembly into the new AppDomain, construct an object, marshal
        // it back to our AD (we really get a reference to a proxy)
        // 这一步导致线程切换到新的 AppDomain
        mbrt = (MarshalByRefType)
               ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");

        // 执行完后,线程切换回来
        // The CLR lies about the type
        // 1. 在内存中,mbrt的真正类型是一个「代理类型」,它有几个私有字段标明了「源AppDomain和 源对象」
        // 2. mbrt的getType,做了特殊处理,返回「源对象」的类型
        Console.WriteLine("Type={0}", mbrt.GetType());

        // Prove that we got a reference to a proxy object
        // IsTransparentProxy,通过这个方法,证明mbrt确实是「代理类型」
        Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));

        // This looks like we're calling a method on MarshalByRefType but, we're not.
        // We're calling a method on the proxy type. The proxy transitions the thread「切换」
        // to the AppDomain owning the object and calls this method on the real object.
        mbrt.SomeMethod();

        // Unload the new AppDomain
        AppDomain.Unload(ad2);

        // mbrt refers to a valid proxy object; the proxy object refers to an invalid AppDomain
        try
        {
            // We're calling a method on the proxy type. The AD is invalid, exception is thrown
            mbrt.SomeMethod();
            Console.WriteLine("Successful call.");
        }
        catch (AppDomainUnloadedException)
        {
            Console.WriteLine("Failed call.");
        }
        #endregion


        // *** DEMO 2: Cross-AppDomain Communication using Marshal-by-Value
        #region demo2
        Console.WriteLine("{0}Demo #2", Environment.NewLine);

        // Create new AppDomain (security & configuration match current AppDomain)
        ad2 = AppDomain.CreateDomain("AD #2", null, null);

        // Load our assembly into the new AppDomain, construct an object, marshal
        // it back to our AD (we really get a reference to a proxy)
        mbrt = (MarshalByRefType)
               ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");

        // The object's method returns a COPY of the returned object;
        // the object is marshaled by value (not be reference).
        MarshalByValType mbvt = mbrt.MethodWithReturn();

        // Prove that we did NOT get a reference to a proxy object
        Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbvt));

        // This looks like we're calling a method on MarshalByValType and we are.
        Console.WriteLine("Returned object created " + mbvt.ToString());

        // Unload the new AppDomain
        AppDomain.Unload(ad2);
        // mbvt refers to valid object; unloading the AppDomain has no impact.

        try
        {
            // We're calling a method on an object; no exception is thrown
            Console.WriteLine("Returned object created " + mbvt.ToString());
            Console.WriteLine("Successful call.");
        }
        catch (AppDomainUnloadedException)
        {
            Console.WriteLine("Failed call.");
        }
        #endregion


        // DEMO 3: Cross-AppDomain Communication using non-marshalable type
        #region demo3
        Console.WriteLine("{0}Demo #3", Environment.NewLine);

        // Create new AppDomain (security & configuration match current AppDomain)
        ad2 = AppDomain.CreateDomain("AD #2", null, null);

        // Load our assembly into the new AppDomain, construct an object, marshal
        // it back to our AD (we really get a reference to a proxy)
        mbrt = (MarshalByRefType)
               ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");

        // The object's method returns an non-marshalable object; exception
        try
        {
            NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        // We won't get here...
        #endregion
    }
예제 #5
0
        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;

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

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

            // 将我们的程序集加载到新AppDomain中,构造一个对象,把它
            // 封送回我们的AppDomain(实际得到对一个代理的引用)
            mbrt = (MarshalByRefType)
                   ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");

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

            // 证明得到的是对一个代理对象的引用
            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));

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

            // 卸载新的AppDomain
            AppDomain.Unload(ad2);

            // mbrt引用一个有效的代理对象;代理对象引用一个无效的AppDomain
            try
            {
                // 在代理类型上调用一个方法,AppDomain无效,造成抛出异常
                mbrt.SomeMethod();
                Console.WriteLine("Successful call.");
            }
            catch (AppDomainUnloadedException)
            {
                Console.WriteLine("Failed call.");
            }

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

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

            // 将我们的程序集加载到新AppDomain中,构造一个对象,把它
            // 封送回我们的AppDomain(实际得到对一个代理的引用)
            mbrt = (MarshalByRefType)
                   ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");

            // 对象的方法返回所返回对象的副本;
            // 对象按值(而非按引用)封送
            MarshalByValType mbvt = mbrt.MethodWithReturn();

            // 证明得到的不是对一个代理对象的引用
            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbvt));

            // 看起来是在MarshalByValType上调用一个方法,实际也是如此
            Console.WriteLine("Returned object created " + mbvt.ToString());

            // 卸载新的AppDomain
            AppDomain.Unload(ad2);
            // mbvt引用有效的对象:卸载AppDomain没有影响

            try
            {
                // 我们是在对象上调用一个方法:不会抛出异常
                Console.WriteLine("Returned object created " + mbvt.ToString());
                Console.WriteLine("Successful call.");
            }
            catch (AppDomainUnloadedException)
            {
                Console.WriteLine("Failed call.");
            }

            // DEMO 3: 使用不可封送的类型进行跨AppDomain通信 ***
            Console.WriteLine("{0}Demo #3", Environment.NewLine);

            // 新建一个AppDomain(从当前AppDomain继承安全性和配置)
            ad2 = AppDomain.CreateDomain("AD #2", null, null);
            // 将我们的程序集加载到新AppDomain中,构造一个对象,把它
            // 封送回我们的AppDomain(实际得到对一个代理的引用)
            mbrt = (MarshalByRefType)
                   ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");

            // 对象的方法返回一个不可封送的对象:抛出异常
            NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName);
            // 这里永远执行不到...
        }
        public static void RunAndExplore()
        {
            // Get a reference to the AppDomain that the calling thread is executing in
            AppDomain adCallingThreadDomain = Thread.GetDomain();

            // Every AppDomain is assigned a friendly string name (helpful for debugging)
            // Get this AppDomain's friendly string name and display it
            String callingDomainName = adCallingThreadDomain.FriendlyName;

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

            // Get and display the assembly in our AppDomain that contains the 'Main' method
            String exeAssembly = Assembly.GetEntryAssembly().FullName;

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

            // Define a local variable that can refer to an AppDomain
            AppDomain ad2 = null;

            #region *** DEMO 1: Cross­AppDomain Communication Using Marshal­by­Reference ***
            Console.WriteLine("{0}Demo #1", Environment.NewLine);

            // Create new AppDomain (security and configuration match current AppDomain)
            ad2 = AppDomain.CreateDomain("AD #2", null, null);
            MarshalByRefType mbrt = null;
            // Load our assembly into the new AppDomain, construct an object, marshal
            // it back to our AD (we really get a reference to a proxy)
            mbrt = (MarshalByRefType)
                   ad2.CreateInstanceAndUnwrap(exeAssembly, typeof(MarshalByRefType).FullName);
            Console.WriteLine("Type={0}", mbrt.GetType()); // The CLR lies about the type
            // Prove that we got a reference to a proxy object
            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));

            Console.WriteLine("Try call SomeMethod()");
            // This looks like we're calling a method on MarshalByRefType but we're not.
            // We're calling a method on the proxy type. The proxy transitions the thread
            // to the AppDomain owning the object and calls this method on the real object.
            mbrt.SomeMethod();
            Console.WriteLine("Successful call.");

            Console.WriteLine("Unload the {0}", ad2.FriendlyName);
            // Unload the new AppDomain
            AppDomain.Unload(ad2);
            // mbrt refers to a valid proxy object; the proxy object refers to an invalid AppDomain
            try
            {
                Console.WriteLine("Try call SomeMethod()");
                // We're calling a method on the proxy type. The AD is invalid, exception is thrown
                mbrt.SomeMethod();
                Console.WriteLine("Successful call.");
            }
            catch (AppDomainUnloadedException e)
            {
                Console.WriteLine("Failed call - {0}", e.GetType());
            }
            #endregion

            #region *** DEMO 2: Cross­AppDomain Communication Using Marshal­by­Value ***
            Console.WriteLine("{0}Demo #2", Environment.NewLine);

            // Create new AppDomain (security and configuration match current AppDomain)
            ad2 = AppDomain.CreateDomain("AD #2", null, null);

            // Load our assembly into the new AppDomain, construct an object, marshal
            // it back to our AD (we really get a reference to a proxy)
            mbrt = (MarshalByRefType)
                   ad2.CreateInstanceAndUnwrap(exeAssembly, typeof(MarshalByRefType).FullName);

            // The object's method returns a COPY of the returned object;
            // the object is marshaled by value (not by reference).
            MarshalByValType mbvt = mbrt.MethodWithReturn();

            // Prove that we did NOT get a reference to a proxy object
            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbvt));
            // This looks like we're calling a method on MarshalByValType and we are.
            Console.WriteLine("Returned object created, try call ToString() call \r\n" + mbvt.ToString());
            Console.WriteLine("Successful call.");

            Console.WriteLine("Unload the {0}", ad2.FriendlyName);
            // Unload the new AppDomain
            AppDomain.Unload(ad2);
            // mbvt refers to valid object; unloading the AppDomain has no impact.
            try
            {
                // We're calling a method on an object; no exception is thrown
                Console.WriteLine("Returned object created try call ToString() call \r\n" + mbvt.ToString());
                Console.WriteLine("Successful call.");
            }
            catch (AppDomainUnloadedException e)
            {
                Console.WriteLine("Failed call - {0}", e.GetType());
            }
            #endregion

            #region *** DEMO 3: Cross­AppDomain Communication Using non­marshalable type ***
            Console.WriteLine("{0}Demo #3", Environment.NewLine);

            // Create new AppDomain (security and configuration match current AppDomain)
            ad2 = AppDomain.CreateDomain("AD #2", null, null);

            // Load our assembly into the new AppDomain, construct an object, marshal
            // it back to our AD (we really get a reference to a proxy)
            mbrt = (MarshalByRefType)
                   ad2.CreateInstanceAndUnwrap(exeAssembly, typeof(MarshalByRefType).FullName);

            try
            {
                // The object's method returns a non­marshalable object;
                NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName); // exception
                Console.WriteLine("Successful call.");                               // We won't get here...
            }
            catch (SerializationException e)
            {
                Console.WriteLine("Failed call - {0}", e.GetType());
            }

            Console.ReadKey();

            #endregion
        }
예제 #7
0
        public static void MainAppdomainAndHost()
        {
            Console.WriteLine(Guid.NewGuid());
            //Clr via 528页
            //获取对Appdomain的一个引用
            AppDomain adCallThreadDomain = Thread.GetDomain();

            String callingDomainName = adCallThreadDomain.FriendlyName;

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

            String exeAssembly = Assembly.GetEntryAssembly().FullName;

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

            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, "MarshalByRefType");

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

            //证明得到的是一个代理对象的引用
            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));

            mbrt.SomeMethod();

            AppDomain.Unload(ad2);

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

            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(mbvt));
            Console.WriteLine("Returned object created {0}", mbvt);

            AppDomain.Unload(ad2);
            try
            {
                Console.WriteLine("Returned object created {0}", mbvt);
                Console.WriteLine("Successful call.");
            }
            catch (Exception)
            {
                Console.WriteLine("Failed call.");
            }


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

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

            NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName);

            Console.WriteLine("Continue.......");

            Console.Read();
        }