Я экспериментирую с идеями об использовании AppDomain для управления устаревшим кодом, содержащим множество статических полей в многопоточной среде.
Я прочитал ответы на этот вопрос: Как использовать 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.Однако вместо этого я получил:
0
1
2
3
4
5
, который говорит мне, что они все еще используют одну и ту же копию статического поля Value.Может кто-нибудь сказать мне, что я сделал не так?
Обновление:
Я попробовал предложение Эрика, теперь я вызываю метод 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();