如何跨AppDomains发送XElement对象

时间:2012-09-20 15:55:38

标签: c# appdomain

我有一个从不同的dll文件加载外部程序集的应用程序。我将程序集加载到之前创建的另一个域。所有程序集都返回XElement对象,我需要将此对象用于主AppDomain中的其他方法,但XElement对象没有Seri​​alizable属性,这就是为什么我不能按原样发送此对象。从外部库获取XElement对象非常重要。我尝试使用序列化,但每次我都失败了。

我尝试创建一些wrap类。这个类只是从XElement创建流,我尝试从主域中读取此流,但此时此流已关闭。

如果有人帮我解决这个问题,我将非常高兴。 谢谢你提前。

private XElement CallModule(string modulePath, string moduleName, 
  Dictionary<string, string> parameters)
{
  AppDomainSetup moduleDomainSetup = new AppDomainSetup();
  moduleDomainSetup.ApplicationBase = AppDomain.CurrentDomain.RelativeSearchPath;
  AppDomain moduleDomain = 
    AppDomain.CreateDomain("moduleDomain", null, moduleDomainSetup);

  try
  {
     Module remoteobj =  (Module)moduleDomain.CreateInstanceFromAndUnwrap(
       HttpContext.Current.Request.MapPath(modulePath),
       moduleName + "." + moduleName);
     Module.WrappedStream remoteResult = 
       remoteobj.Execute(queryString["command"], parameters);

     XElement res = XElement.Load(remoteResult.Stream);
     return res;
  }
  catch (Exception ex)
  {
    throw ex;
  }
  finally
  {
    AppDomain.Unload(moduleDomain);
  }
}

3 个答案:

答案 0 :(得分:1)

您可以使用XElement.Save将其保存到TextWriter或Stream

答案 1 :(得分:0)

您不能使用XElement跨AppDomain边界。可能的原因 - XElement可以表示巨大的对象树/必须在AppDomain边界编组的大量数据。

虽然你可以让你的代码工作(即通过保存到流和重新加载),但这可能不是最好的主意。您将丢失元素(即父元素)的上下文,并且可能无意中序列化/反序列化大量数据。考虑重构,以便在创建它的新AppDomain中处理XElement的数据,而不是将自定义对象(ref的serialzable或marshal)返回到主AppDomain。

注意:

  • 我假设您的示例代码只是示例,创建/拆除AppDomain以调用单一方法并不是地球上最快的事情。如果它是一次性操作可能完全没问题,但如果它以任何非常重要的频率重复,请务必检查性能是否符合您的目标。
  • 如果您只需要catch,则不需要throw / finally(再次假设实际代码超过throw

答案 2 :(得分:0)

Module remoteobj =  (Module)moduleDomain.CreateInstanceFromAndUnwrap(
       HttpContext.Current.Request.MapPath(modulePath),
       moduleName + "." + moduleName);
     Module.WrappedStream remoteResult = 
       remoteobj.Execute(queryString["command"], parameters);

     XElement res = XElement.Load(remoteResult.Stream);
     return res;

可以序列化modulePath,moduleName和参数,然后使用modulePath,moduleName和parameters重新创建XElement对象,而不是尝试序列化XElement。

你也可以用Command Pattern试试吗?