2

LoaderOptimization.MultiDomain启用后我会遇到一些问题。不知何故,当在某些特定场景中找不到程序集时,它不再触发 AssemblyResolve 事件。

我把它缩小到一个有 2 个项目的复制案例。您可以在这里下载完整的解决方案: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)但将 Copy Local 设置为 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。

4

0 回答 0