3

以下示例基于“来回传递值 appdomains ”,其中 Marc Gravell 为有关 appdomains 之间的 .Net 远程处理的问题提供了一个非常好的答案。我所做的是将它扩展为(非常天真的?)期望它也应该适用于字符串数组。

问题是它只能以一种方式工作——创建的 appdomain 可以访问数组,但只能是只读的。我想要的是将更新后的数组元素也恢复到原始 appdomain 中。我什至想用 List<> 和 Dictionary<> 对象来做这件事。这可能吗?

using System;

namespace StackoverflowSample
{
   class MyBoundaryObject : MarshalByRefObject
   {
      public void SomeMethod(AppDomainArgs ada)
      {
         Console.WriteLine(AppDomain.CurrentDomain.FriendlyName + "; executing");
         ada.MyString = "working!";
         ada.MyStringArray[0] = "working!";
         string s = ada.MyStringArray[0];  // s is assigned value "a"!!!
      }
   }


   public class AppDomainArgs : MarshalByRefObject
   {
      public string MyString { get; set; }
      public string[] MyStringArray { get; set; }
   }


   static class Program
   {
      static void Main()
      {
         AppDomain domain = AppDomain.CreateDomain("Domain666");
         MyBoundaryObject boundary = (MyBoundaryObject)
              domain.CreateInstanceAndUnwrap(
                 typeof(MyBoundaryObject).Assembly.FullName,
                 typeof(MyBoundaryObject).FullName);

         AppDomainArgs ada = new AppDomainArgs();
         ada.MyString = "abc";
         ada.MyStringArray = new string[] { "a", "b" };
         Console.WriteLine("Before: " + ada.MyString + " " + ada.MyStringArray[0]);

         boundary.SomeMethod(ada);

         Console.WriteLine("After: " + ada.MyString + " " + ada.MyStringArray[0]);
         Console.ReadKey();
         AppDomain.Unload(domain);
      }
   }
}
4

1 回答 1

1

有时,我也有将更新后的列表返回给 Main AppDomain 的要求,我使用创建一个new instance of a Listand的解决方法解决了这个问题assign the desired values。这应该适合你 -

ada.MyStringArray = new string[] { "working!", "b" };
string s = ada.MyStringArray[0];  // s will be assigned value "working!"!!!

更新

我猜你必须在从远程方法返回之前clone实例化并实例化 a 。new instance它之所以working简单的原因string是-

字符串是immutableie 每次你用不同的值初始化它时,new instance在幕后为它创建一个有点像new String(). 因此,更新在其他 appDomain 中可见。

我尝试了这个小东西,StringBuildermutable当您更改对象的内容时,不会为它们创建新实例。

public class AppDomainArgs : MarshalByRefObject
{
    public StringBuilder MyStringBuilder { get; set; }
}

public void SomeMethod(AppDomainArgs ada)
{
    Console.WriteLine(AppDomain.CurrentDomain.FriendlyName + "; executing");
    ada.MyString = "working!";
    ada.MyStringBuilder.Append(" working!");
}

现在,看看输出 -

Console.WriteLine("Before: " + ada.MyString + " " + ada.MyStringArray[0] + " " + 
                      ada.MyStringBuilder);    
boundary.SomeMethod(ada);    
Console.WriteLine("After: " + ada.MyString + " " + ada.MyStringArray[0] + " "
                      ada.MyStringBuilder);

您将看到该StringBuilder对象未更改。理想情况下,它的值应该是"a working!"但仍然是"a"

于 2012-10-27T14:24:56.447 回答