使用SetData,GetData实现AppDomain之间的数据,对象传递

AppDomain有SetData与GetData操作,这使得应用程序域之间的数据与对象传递相当的简单,不过就算您不知道这个方法,也可以直接使用远程对象调用实体对象设置,这与Remoting的设置方法是一样的.我们下面讨论的重要问题是对象传递之后,怎样保持对象的生命周期.

下面引用几个网上流传的代码

1,传递数据

public class MyType: MarshalByRefObject
{
public int i;
}

public class Program
{
public static void Test()
{
AppDomain domain
= AppDomain.CurrentDomain;
MyType t
= domain.GetData("arg") as MyType;

Console.WriteLine(
"[{0}] {1}", domain.FriendlyName, t.i);
if (domain.FriendlyName == "NewDomain") t.i = 1000000000;
}

static void Main()
{
AppDomain ndomain
= AppDomain.CreateDomain("NewDomain");
MyType t
= new MyType();

// 或者使用下列代码在ndomain上创建MyType对象。
// string assemblyName = Assembly.GetExecutingAssembly().FullName;
// string typeName = typeof(MyType).FullName;
// MyType t = ndomain.CreateInstanceAndUnwrap(assemblyName, typeName) as MyType;

AppDomain.CurrentDomain.SetData(
"arg", t);
ndomain.SetData(
"arg", t);

t.i
= 13;
Test();
ndomain.DoCallBack(
new CrossAppDomainDelegate(Test));
Test();
}
}



这个操作相当的方便,也不涉及到对象生命周期的管理.

2,远程对象调用

[Serializable]
public class MyType
{
public int i;
}

public class Program
{
public static void Test()
{
AppDomain domain
= AppDomain.CurrentDomain;
MyType t
= domain.GetData("arg") as MyType;

Console.WriteLine(
"[{0}] {1}", domain.FriendlyName, t.i);
if (domain.FriendlyName == "NewDomain") t.i = 1000000000;
}

static void Main()
{
AppDomain ndomain
= AppDomain.CreateDomain("NewDomain");
MyType t
= new MyType();

AppDomain.CurrentDomain.SetData(
"arg", t);
ndomain.SetData(
"arg", t);

t.i
= 13;
Test();
ndomain.DoCallBack(
new CrossAppDomainDelegate(Test));
Test();
}
}


 

如果您使用的是一次性调用,上面的代码一点问题也没有,不过要是你使用的是生命周期比较长的对象,如这个远程对象要永久保持的,以便应用程序域之间进行不间断的调用,这种情况下生命周期的问题就出现,因为对象在应用程序域中调用是远程对象调用,对象的生命周期只有5分钟,过了之后,对象就会被垃圾回收机制强制回收.于是应用程序域之间的操作就被间断.
    经过测试,直接使用延长生命周期的方法是最容易的.
    1,客户端获取远程对象
    两个应用服务器中,获取另一个应用程序域的对象中,此应用程序域被当成是客户端.需要使用RemotingServices.GetLifetimeService方法来获取远程对象.
    2,延长生命周期
    使用ILease.Renew来延长对象的生命周期,如直接延长3650天.
    注意:
    使用重写InitializeLifetimeService来延长生命周期的方法在这里不能使用.因为对象在创建的时间根本不可能是远程对象.

    同样,如果您在处理Event时,也会存在生命周期的问题,了解上述的情况可以帮助您更好地解决应用程序域之间的持久交互的问题.


posted @ 2011-03-31 16:15  天地任我飞翔  Views(964)  Comments(0)    收藏  举报