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

问题描述 投票:20回答:4

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

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

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

提前致谢。

c# reflection assemblies
4个回答
19
投票

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

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

GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));

这避免了new。请注意,这将被加载,但不会加载JIT等。

如果你愿意,你可以在BG线程上做到:

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

2
投票

我相信Assembly.Load就是这样。

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

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

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

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

container.ResolveAll<Form>();

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

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

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


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

那会吗?


0
投票

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

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

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

assembly name in visual studio

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

© www.soinside.com 2019 - 2024. All rights reserved.