статические переменные внутри предметной области - PullRequest
0 голосов
/ 04 июня 2018

У меня есть следующие классы в сборке библиотеки C #.

public static class TestClass
{
    static int counter = 0;
    static TestClass()
        {
            System.Diagnostics.Debug.Print("TestLibrary.TestClass is constructed...");
        }

        public static void Say()
        {
            System.Diagnostics.Debug.Print($"TestClass.Say called {counter++} times");
        }
}

[Serializable]
public class TestLibraryProxy
{
    static int _executionCount = 0;
        public void Execute()
        {
            System.Diagnostics.Debug.Print($"TestLibraryProxy Execute [{_executionCount++}]");
            TestClass.Say();
            TestClass.Say();
        }
}

Из другого приложения C # Я пытаюсь загрузить вышеуказанную сборку в домен приложения и вызвать метод TestLibraryProxy.Execute ().

class Program
{
    static void Main(string[] args)
    {
        CreateAppDomainAndCallStaticMethod("MyDomain1");
        CreateAppDomainAndCallStaticMethod("MyDomain2");
        CreateAppDomainAndCallStaticMethod("MyDomain3");
        CreateAppDomainAndCallStaticMethod("MyDomain4");
    }

    private static void CreateAppDomainAndCallStaticMethod(string domainName)
    {
        AppDomain domain = AppDomain.CreateDomain(domainName);
        var k = domain.CreateInstanceAndUnwrap("TestLibrary", typeof(TestLibraryProxy).FullName) as TestLibraryProxy;
        k.Execute();
        AppDomain.Unload(domain);
    }
}
Output
TestLibraryProxy Execute [0]
TestLibrary.TestClass is constructed...
TestClass.Say called 0 times
TestClass.Say called 1 times
TestLibraryProxy Execute [1]
TestClass.Say called 2 times
TestClass.Say called 3 times
TestLibraryProxy Execute [2]
TestClass.Say called 4 times
TestClass.Say called 5 times
TestLibraryProxy Execute [3]
TestClass.Say called 6 times
TestClass.Say called 7 times

Я заметил, что значение статических счетчиков в TestClass сохраняется во всех доменах приложения.Это значение сохраняется, даже если я загружаю и выгружаю домен приложения несколько раз.

Я прочитал, что статические переменные хранятся на уровне домена приложения.Но, похоже, это не так?Любая идея, как CLR управляет статическими данными в доменах приложений.

1 Ответ

0 голосов
/ 04 июня 2018

Это потому, что TestLibraryProxy было помечено [Serializable].

Вместо этого оно должно наследоваться от MarshalByRefObject.

По сути, вы создали объект в другом AppDomain затем скопировали (сериализовали) в оригинал AppDomain.Использование MarshalByRefObject позволяет избежать этого.Это гарантирует, что объект не будет скопирован - вместо этого вы будете иметь дело со ссылкой на исходный объект (работающий в другом AppDomain).

Если вы сделаете это изменение

public class TestLibraryProxy : MarshalByRefObject

выход изменяется на:

TestLibraryProxy Execute [0]
TestLibrary.TestClass is constructed...
TestClass.Say called 0 times
TestClass.Say called 1 times

повторяется несколько раз

...