懒惰的Accessibility.dll加载?

时间:2012-03-16 11:25:18

标签: c# .net wpf

在我的WPF应用程序中,用户第一次打开菜单时会因延迟加载Accessibility.dll而导致暂停。

你可以想象这非常烦人,所以我想在启动时强制加载这个程序集。我已经尝试了几种方法,没有运气。例如,使用Assembly.Load()或AppDomain.Load()。这些调用都不会导致程序集加载(即我没有得到任何AssemblyLoaded事件。我已经尝试直接引用这些方法以获取正确的AssemblyName来调用这些方法,但仍然没有运气。

实现这一目标的正确方法是什么?

非常感谢 丹

编辑:在装配加载时调用堆栈(单击菜单后)

mscorlib.dll中!System.AppDomain.OnAssemblyLoadEvent(System.Reflection.RuntimeAssemblyLoadedAssemly [原产于管理过渡]
[管理到原生过渡]
PresentationFramework.dll!System.Windows.Controls.Primitives.Popup.CreateWindow(bool asyncCall)

Popup的电话是:

_secHelper.ForceMsaaToUiaBridge(_popupRoot.Value);

2 个答案:

答案 0 :(得分:2)

是的,你可以使用反射(RuntimeHelpers.PrepareMethod)强制JIT编译器在后台线程中编译你想要的方法。这是一个CodeProject article,描述了这一点。

RuntimeHelpers.PrepareMethod是线程安全的,因此在这种情况下使用是安全的。

这是代码,稍作修改以排除泛型和P / Invoked函数:

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();

答案 1 :(得分:0)

我假设您的Accessibility.dll中有一个类型要实例化或使用。

我认为在这里花费时间的是JIT,所以要强制JIT只运行创建/使用对象的实例。当我处于类似的情况时,我倾向于添加像Accessibility.RunJIT()这样的方法。我所做的只是创建一个类的实例。

你也可以看看NGen。 http://msdn.microsoft.com/en-us/library/6t9t5wcf(v=vs.110).aspx