本文代码来源: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);
}
}
}