预加载.NET程序集的好方法

时间:2011-02-04 07:53:44

标签: c# reflection assemblies

在我的应用中,我需要在鼠标点击时显示一个表单。问题是表单在另一个程序集中,并且由于程序集加载的惰性,很可能在按下鼠标按钮时尚未加载程序集。因此,在表单最终出现之前,我所拥有的是非常明显的暂停。

通过在初始化方法中调用new FormFromAnotherAssembly(),我能够提出一个愚蠢的修复方法。那当然是照顾好事情,停顿不再存在,但它非常难看。我唯一喜欢这个解决方案的是,如果我想使用类似Assembly.Load的东西,我不必弄乱路径和汇编名称。

那么,如果我想确保在实际需要之前加载程序集,那么选择好的,强大的解决方案是什么?

提前致谢。

4 个答案:

答案 0 :(得分:19)

初始化中的显式预加载可能仍是您的最佳选择。

typeof(SomeTypeFromAnotherAssembly)应该足够了 - 还有一些无法优化的不透明方法;也许:

GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));

这可以避免new。请注意,这将是加载,但不是JITted等。

如果您愿意,可以在BG线程上执行此操作:

private static void LoadSomeStuff(object state) {
    GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));
}
...
ThreadPool.QueueUserWorkItem(LoadSomeStuff);

答案 1 :(得分:2)

我相信Assembly.Load就是这样。

在应用程序启动期间,您应该找到可插拔的模块,插件或任何其他运行时,并将其程序集加载到应用程序的域(AppDomain)中。

或者另一个更好的选择:为什么不使用反转控制?

你可以使用Castle Windsor。假设您在运行时加载了4个表单,因此,您可以创建4个Form类组件,它们的实现是在程序生命周期中加载的4个表单。

如何使用此方法预加载?您只需解析所有类型为Form的依赖项/组件,并获得它:

container.ResolveAll<Form>();

稍后你会得到一个特定的表格:

container.Resolve<Form>("CustomersForm"); // Just an example

如果您不知道控制倒置,请注释掉,我会帮助您,没问题! :)

答案 2 :(得分:1)

var yourAppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Assembly.Load(Path.Combine(yourAppPath, "formAssembly.dll"));

那会吗?

答案 3 :(得分:0)

我认为最简单的方法是在Assembly.Load()中使用程序集名称:

System.Reflection.Assembly.Load("ICSharpCode.AvalonEdit");

您可以在Visual Studio中的引用属性下找到程序集名称:

assembly name in visual studio

这样你可以避免输入dll文件路径等。我用它来加速加载使用这个DLL的对话框。一旦程序主窗口完全加载,它就会启动一个只调用Assembly.Load()的后台线程。当用户打开此对话框时,加载此DLL的小延迟就消失了。