以下示例基于“Passing values back and forth appdomains”,其中Marc Gravell对appdomains之间的.Net远程处理问题提供了非常好的答案。我所做的是扩展它(非常天真?)期望它应该也适用于一个字符串数组。
问题是它只能以一种方式工作 - 创建的appdomain可以访问数组,但只能是readonly。我想要的是将更新的数组元素也恢复到原来的appdomain中。我甚至想用List<>这样做和词典<>对象。这可能吗?
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);
}
}
}
答案 0 :(得分:1)
有时候我也有这个要求将更新后的列表返回给主AppDomain,我使用创建new instance of a List
和assign the desired values
的解决方法解决了这个问题。这应该适合你 -
ada.MyStringArray = new string[] { "working!", "b" };
string s = ada.MyStringArray[0]; // s will be assigned value "working!"!!!
<强>更新强>
我猜你必须clone
实例并在从远程方法返回之前实例化new instance
。简单working
为string
的原因是 -
字符串为immutable
,即每次使用不同的值对其进行初始化时,会在幕后创建一个new instance
,就像new String()
一样。因此,更新在其他appDomain中可见。
我用StringBuilder
尝试了这个小事mutable
,但是当你改变对象的内容时,没有为它们创建新的实例。
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"
。