LoaderOptimization.MultiDomain заставляет AssemblyResolve не запускаться

У меня есть некоторые проблемы, как только LoaderOptimization.MultiDomainвключен. Почему-то больше не запускается событие AssemblyResolve, когда сборка не найдена в некоторых конкретных сценариях.

Я сузил его до случая с двумя проектами. Вы можете скачать полное решение здесь: https://developercommunity.visualstudio.com/storage/attachments/24787-appdomainresolvetest.zip

Допустим, у меня есть программа высшего уровня:

class AppProgram
{
    // Comment this and both Resolve1 and Resolve2 will happen
    // If enabled, Resolve2 doesn't happen
    [LoaderOptimization(LoaderOptimization.MultiDomain)]
    static void Main(string[] args)
    {
        var applicationPath = AppDomain.CurrentDomain.BaseDirectory;

        var appDomainSetup = new AppDomainSetup { ApplicationBase = Directory.GetParent(applicationPath).FullName };
        var otherDomain = AppDomain.CreateDomain("other domain", AppDomain.CurrentDomain.Evidence, appDomainSetup);
        otherDomain.DoCallBack(TestCallback);
    }

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        Console.WriteLine($"Resolve1 {args.Name}");
        return null;
    }

    private static void TestCallback()
    {
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        var remoteAssembly = AppDomain.CurrentDomain.Load("ConsoleApplication1");
        remoteAssembly.EntryPoint.Invoke(null, new object[] { new string[0] });
    }
}

Затем сборка ConsoleApplication1 имеет следующий код:

(Обратите внимание, что ссылка на Newtonsoft.Json (w/ NuGet) имеется, но для параметра "Локальное копирование" задано значение "false", что приводит к преднамеренному разрешению сборки и исключению FileNotFoundException)

class ConsoleProgram
{
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        try
        {
            Test();
        }
        catch (FileNotFoundException)
        {
        }
    }

    private static void Test()
    {
        JsonConvert.SerializeObject(true);
    }


    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        Console.WriteLine($"Resolve2 {args.Name}");
        return null;
    }
}

Что происходит, если LoaderOptimization.MultiDomain атрибут не установлен на Main, вызываются и Resolve1 (из программы верхнего уровня), и Resolve2 (из библиотеки). Однако, как только LoaderOptimization.MultiDomain установлено, вызывается только Resolve1.

В моем реальном приложении MultiDomain очень важен, чтобы избежать JIT и снова инициализировать сборки (сократить время запуска с 5 секунд практически до нуля). В результате я хотел бы понять причину этой ошибки и, надеюсь, найти обходной путь.

Редактировать: даже при попытке жесткого кодирования моего разрешения во время Resolve1 кажется, что он не может кэшировать сборки (загрузка идет медленно). Может быть, MultiDomain работает только для сборок в ApplicationBase? В этом случае, я полагаю, мне придется использовать PrivateBinPath для оптимизации JIT. Хотелось бы узнать, можно ли устранить ошибку AssemblyResolve, потому что еще есть несколько дополнительных сборок, загруженных по внешнему пути, и мне все равно, если они не являются JIT.

0 ответов

Другие вопросы по тегам