在我的WPF应用程序中,当用户第一次打开菜单时,会因为延迟加载Accessibility.dll而暂停。
正如你可以想象的那样,这是非常烦人的,所以我想在启动时强制加载这个程序集。我已经尝试了几种方法,但都没有成功。例如,使用Assembly.Load()或AppDomain.Load()。这些调用都不会导致程序集加载(即,我没有得到任何AssemblyLoaded事件。为了获得调用这些方法的正确AssemblyName,我尝试了直接引用assmebly,但仍然没有成功。
实现这一目标的正确方法是什么?
非常感谢,丹
编辑:在程序集加载时调用堆栈(在单击菜单之后)
mscorlib.dll!System.AppDomain.OnAssemblyLoadEvent(System.Reflection.RuntimeAssemblyLoadedAssemly本机到托管的过渡
托管到本机过渡
PresentationFramework.dll!System.Windows.Controls.Primitives.Popup.CreateWindow(bool asyncCall)
来自弹出窗口的调用是:
_secHelper.ForceMsaaToUiaBridge(_popupRoot.Value);
发布于 2012-03-16 19:43:19
是的,您可以使用反射(RuntimeHelpers.PrepareMethod)来强制JIT编译器在后台线程中编译您想要的方法。下面是一个描述这一点的CodeProject article。
RuntimeHelpers.PrepareMethod是线程安全的,所以在这种情况下使用它是安全的。
以下是代码,略微修改以排除泛型函数和P/调用函数:
Thread jitter = new Thread(() =>
{
var flags = BindingFlags.DeclaredOnly | BindingFlags.NonPublic |
BindingFlags.Public | BindingFlags.Instance |
BindingFlags.Static;
foreach (var assembly in AssembliesToPreload)
foreach (var type in a.GetTypes())
foreach (var method in type.GetMethods(flags))
{
if (method.ContainsGenericParameters ||
method.IsGenericMethod ||
method.IsGenericMethodDefinition)
continue;
if ((method.Attributes & MethodAttributes.PinvokeImpl) > 0)
continue;
RuntimeHelpers.PrepareMethod(method.MethodHandle);
}
}
});
jitter.Priority = ThreadPriority.Lowest;
jitter.Start();发布于 2012-03-16 19:43:39
我假设您的Accessibility.dll中有一个您想要实例化或使用的类型。
我认为在这里花费时间的是JIT,所以要强制JIT运行,只需创建/使用对象的一个实例。当我遇到类似的情况时,我倾向于添加像Accessibility.RunJIT()这样的方法。然后我要做的就是创建一个类的实例。
你也可以看看NGen。http://msdn.microsoft.com/en-us/library/6t9t5wcf(v=vs.110).aspx
https://stackoverflow.com/questions/9736391
复制相似问题