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);
}
}
}
}