以下示例基于“Passing values back and forth appdomains”,其中 Marc Gravell 对应用域之间的 .Net 远程处理问题提供了非常好的答案。我所做的是扩展它(非常天真?)期望它也适用于字符串数组。
问题是它只能以一种方式工作——创建的 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);
}
}
}
有时我也有将更新的列表返回到 Main AppDomain 的要求,我使用创建 List 的新实例
和分配所需值的变通方法解决了它
。这应该适合你 -
ada.MyStringArray = new string[] { "working!", "b" };
string s = ada.MyStringArray[0]; // s will be assigned value "working!"!!!
更新
我想您必须在从远程方法返回之前克隆
实例并实例化一个新实例
。对于简单的 string
,它 work
的原因是 -
字符串是不可变的
,即每次用不同的值初始化它时,都会在幕后为它创建一个新实例
,有点像new String()
。因此,更新在其他 appDomain 中可见。
我用 StringBuilder
尝试了这个小东西,它是可变的
,即当您更改对象的内容时,不会为它们创建新实例。
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"
。
我是一名优秀的程序员,十分优秀!