Переключение домена приложения - PullRequest
2 голосов
/ 20 октября 2011

У меня есть ситуация, когда мне нужно создать (возможно, грязный) тестовый прогон.Идея состоит в том, чтобы использовать что-то вроде Tasks или ThreadPool для одновременного выполнения огромного количества тестов.

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

Примечание: это предположение, основанное на тестировании, которое я проводилв этом я не уверен на 100%.

Я попытался создать новый домен приложений (AppDomain.Create), а затем создал экземпляр класса, используя его(domain.CreateInstanceFromAndUnwrap), и он создает экземпляр, и я могу вызывать методы для него.Проблема в том, что он не работает в новом домене приложений.

Вот код, который у меня есть:

    static void CallBack(BasePerfTest bpf)
    {
        Console.WriteLine("CurrentAppDomain (WithinCallback): {0}", Thread.GetDomain().Id);
        AppDomain newdomain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
        //newdomain.ExecuteAssembly(".\\PerformanceTestRunner.exe", new string[] { bpf.ToString() });
        ProcessRunner pr = (ProcessRunner)newdomain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().Location, "PerformanceTesting.ProcessRunner");
        pr.RunProcess(bpf);
    }

}
[Serializable]
public class ProcessRunner
{
    public void RunProcess(BasePerfTest bpf)
    {
        Console.WriteLine("CurrentAppDomain (WithinPR): {0}", Thread.GetDomain().Id);
    }

}

Теперь я ожидаю, что RunProcess ()метод выполняется в домене, но DomainID остается прежним, и поэтому он сталкивается с проблемой столкновения статики.

Теперь я создал отдельное консольное приложение, и закомментированная строка показывает кодЯ имел обыкновение управлять этим.Этот DID запускался в новом домене, но вопрос в том, почему.

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

Любая помощь очень ценится.

Спасибо, Мартин

Ответы [ 2 ]

4 голосов
/ 20 октября 2011

Существует два способа выставить объекты за границы AppDomain:

  • Serializable - сериализует объект, поэтому вы получаете копию.
  • MarshalByRefObject - создает прокси для вашего объекта, используя удаленное взаимодействие.

Последнее вам нужно для вашего ProcessRunner класса.

Заставьте ваш класс наследоваться от MarshalByRefObject:

public class ProcessRunner : MarshalByRefbject
{
    public void RunProcess(BasePerfTest bpf)
    {
        Console.WriteLine("CurrentAppDomain (WithinPR): {0}", Thread.GetDomain().Id);
    }
}

Когда вы создаете экземпляр класса во втором AppDomain, вы получаете прокси.Пример из документации MarshalByRefObject для MSDN также должен вам помочь - он демонстрирует почти то, что вы пытаетесь сделать.

2 голосов
/ 20 октября 2011

Ваш класс ProcessRunner должен наследоваться от System.MarshalByRefObject.Происходит то, что объект фактически создается во вторичном домене приложения, но когда вы присваиваете его локальной переменной 'pr', он сортирует его по значению обратно в ваш первичный домен приложения, фактически создавая второй экземпляр ProcessRunnerосновной домен приложения.Если вы унаследовали от MarshalByRefObject, вместо этого pr получит прозрачный прокси-объект, который перенаправляет вызовы объекта, находящегося во вторичном домене приложения.

...