AppDomain中的静态字段

我正在尝试使用AppDomain来pipe理一些遗留代码,这些代码在multithreading环境中包含大量的静态字段。

我读这个问题的答案: 如何使用AppDomain限制静态类的线程安全使用的范围? ,认为这是相当有前途的,并决定尝试一个非常简单的类在ClassLibrary1.dll中:

namespace ClassLibrary1 { public static class Class1 { private static int Value = 0; public static void IncrementAndPrint() { Console.WriteLine(Value++); } } } 

这里是我的代码加载组装到2个不同的应用程序域,并调用IncrementAndPrint()几次:

 var appDomain1 = System.AppDomain.CreateDomain("AppDomain1"); var appDomain2 = System.AppDomain.CreateDomain("AppDomain2"); var assemblyInAppDomain1 = appDomain1.Load("ClassLibrary1"); var assemblyInAppDomain2 = appDomain2.Load("ClassLibrary1"); var class1InAppDomain1 = assemblyInAppDomain1.GetType("ClassLibrary1.Class1"); var class1InAppDomain2 = assemblyInAppDomain2.GetType("ClassLibrary1.Class1"); class1InAppDomain1.InvokeMember("IncrementAndPrint", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null); class1InAppDomain1.InvokeMember("IncrementAndPrint", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null); class1InAppDomain1.InvokeMember("IncrementAndPrint", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null); class1InAppDomain2.InvokeMember("IncrementAndPrint", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null); class1InAppDomain2.InvokeMember("IncrementAndPrint", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null); class1InAppDomain2.InvokeMember("IncrementAndPrint", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null); 

我期待的输出是:

 0 1 2 0 1 2 

因为将存在AppDomain的每个实例的本地静态字段Value的副本。 但是,我得到的是:

 0 1 2 3 4 5 

这告诉我他们仍然全部共享静态字段Value的相同副本。 谁能告诉我我在这里做错了什么?

更新:

我尝试了Erik的build议,现在我调用AppDomain类的CreateInstanceAndUnwrap()方法,而不是调用Load()和GetType(),如下所示。 另外,我已经将IncrementAndPrint转换为实例方法而不是静态方法。 但是,我仍然得到相同的结果。

 var appDomain1 = System.AppDomain.CreateDomain("AppDomain1"); var appDomain2 = System.AppDomain.CreateDomain("AppDomain2"); var class1InAppDomain1 = (Class1)appDomain1.CreateInstanceAndUnwrap("ClassLibrary1", "ClassLibrary1.Class1"); var class1InAppDomain2 = (Class1)appDomain2.CreateInstanceAndUnwrap("ClassLibrary1", "ClassLibrary1.Class1"); class1InAppDomain1.IncrementAndPrint(); class1InAppDomain1.IncrementAndPrint(); class1InAppDomain1.IncrementAndPrint(); class1InAppDomain2.IncrementAndPrint(); class1InAppDomain2.IncrementAndPrint(); class1InAppDomain2.IncrementAndPrint(); 

它看起来像是从另一个appDomain加载到当前的appDomain的types。 因此调用静态方法的代码是从当前的appDomain调用的。

我不知道任何其他方式调用另一个域中的静态方法,而无需在另一个域中创build一个对象的实例,并让该对象调用静态方法。

示例:解决scheme包含2个项目(ClassLibrary和Winforms / Console应用程序)

[ClassLibrary]

 using System; namespace MyLibrary { public class DomainObject : MarshalByRefObject { private static int _Value; private static void IncrementValue() { DomainObject._Value++; } public static int Value { get { return DomainObject._Value; } } public int GetIncrementedValue() { DomainObject.IncrementValue(); return DomainObject.Value; } } } 

[应用]

 private void button1_Click(object sender, EventArgs e) { AppDomain domain1 = AppDomain.CreateDomain("domain1"); AppDomain domain2 = AppDomain.CreateDomain("domain2"); DomainObject object1 = domain1.CreateInstanceAndUnwrap("MyLibrary", "MyLibrary.DomainObject") as DomainObject; DomainObject object2 = domain2.CreateInstanceAndUnwrap("MyLibrary", "MyLibrary.DomainObject") as DomainObject; if (object1 != null) { Console.WriteLine("object 1 Value = " + object1.GetIncrementedValue().ToString()); Console.WriteLine("object 1 Value = " + object1.GetIncrementedValue().ToString()); Console.WriteLine("object 1 Value = " + object1.GetIncrementedValue().ToString()); } if (object2 != null) { Console.WriteLine("object 2 Value = " + object2.GetIncrementedValue().ToString()); Console.WriteLine("object 2 Value = " + object2.GetIncrementedValue().ToString()); Console.WriteLine("object 2 Value = " + object2.GetIncrementedValue().ToString()); } /* Unload the Domain and re-create * This should reset the Static Value in the AppDomain */ AppDomain.Unload(domain1); domain1 = AppDomain.CreateDomain("domain1"); object1 = domain1.CreateInstanceAndUnwrap("MyLibrary", "MyLibrary.DomainObject") as DomainObject; if (object1 != null) { Console.WriteLine("object 1 Value = " + object1.GetIncrementedValue().ToString()); Console.WriteLine("object 1 Value = " + object1.GetIncrementedValue().ToString()); Console.WriteLine("object 1 Value = " + object1.GetIncrementedValue().ToString()); } if (object2 != null) { Console.WriteLine("object 2 Value = " + object2.GetIncrementedValue().ToString()); Console.WriteLine("object 2 Value = " + object2.GetIncrementedValue().ToString()); Console.WriteLine("object 2 Value = " + object2.GetIncrementedValue().ToString()); } } 

生成的结果:

 object 1 Value = 1 object 1 Value = 2 object 1 Value = 3 object 2 Value = 1 object 2 Value = 2 object 2 Value = 3 object 1 Value = 1 object 1 Value = 2 object 1 Value = 3 object 2 Value = 4 object 2 Value = 5 object 2 Value = 6