Я экспериментирую с идеями, использующими 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. Однако вместо этого я получил:
0
1
2
3
4
5
, который говорит мне, что они все еще используют одну и ту же копию статического поля Значение. Может ли кто-нибудь сказать мне, что я сделал неправильно здесь?
Update:
Я попытался предложение Эрика, теперь я называю() метод класса AppDomain вместо вызова Load() и GetType(), как показано ниже CreateInstanceAndUnwrap. Кроме того, я преобразовал 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 он статический метод в текущем домене приложения. Вам нужно создать метод Instance, который вызывает метод Static класса Class1. – 2010-11-28 21:39:41
Привет Эрик, если вы посмотрите мой обновленный исходный код, я преобразовал метод IncrementAndPrint() в метод экземпляра и использовал CreateInstanceAndUnWrap() для создания экземпляров в соответствующих доменах приложений. Тем не менее, я все равно получаю тот же результат. – oscarkuo 2010-11-29 00:23:15