启用LoaderOptimization.MultiDomain
后,我遇到了一些问题。
不知何故,当在某些特定场景中找不到程序集时,它不会再触发AssemblyResolve事件。
我把它缩小到一个有2个项目的repro案例。 您可以在此处下载完整解决方案: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;
}
}
如果未在Main上设置LoaderOptimization.MultiDomain
属性,则会调用Resolve1(来自顶级程序)和Resolve2(来自库)。
但是,只要设置LoaderOptimization.MultiDomain
,就会调用Resolve1。
在我的实际应用程序中,MultiDomain对于避免JIT并再次初始化程序集至关重要(将第二次启动时间从5秒减少到几乎没有)。 因此,我想了解这个bug的根本原因,并希望找到一个解决方法。
编辑:即使在Resolve1期间尝试对我的解析进行硬编码时,它似乎无法缓存程序集(加载速度很慢)。
也许MultiDomain仅适用于ApplicationBase
中的程序集?
在这种情况下,我想我将不得不使用PrivateBinPath来优化JIT。
仍然想知道是否可以解决AssemblyResolve错误,因为还有一些额外的程序集从外部路径加载,如果它们不是JIT我不在乎。