我正在嘗試使用AppDomain來管理一些遺留代碼,這些代碼在多線程環境中包含大量靜態字段。AppDomain中的靜態字段
我看了回答了這個問題:How to use an AppDomain to limit a static class' scope for thread-safe use?,認爲這是相當有前途,並決定在裝配ClassLibrary1.dll一個非常簡單的類來嘗試一下:
namespace ClassLibrary1
{
public static class Class1
{
private static int Value = 0;
public static void IncrementAndPrint()
{
Console.WriteLine(Value++);
}
}
}
,這裏是一個加載assemblyinto 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
它告訴我他們仍然都共享相同的副本的靜態字段值。 任何人都可以告訴我我在這裏做錯了什麼?
更新:
我想埃裏克的建議,現在我叫CreateInstanceAndUnwrap(如下圖)在AppDomain類的方法,而不是調用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();
你打電話給t他是當前應用程序域中的靜態方法。您需要創建一個調用Class1類的Static方法的Instance方法。 – 2010-11-28 21:39:41
嗨Erik,如果你看看我更新的源代碼,我已經將IncrementAndPrint()轉換爲實例方法,並使用CreateInstanceAndUnWrap()在各個應用程序域中創建實例。然而,我仍然得到相同的結果 – oscarkuo 2010-11-29 00:23:15