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

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

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

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

提前致谢。

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

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

 GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly)); 

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

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

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

我相信Assembly.Load就是这样。

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

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

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

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

 container.ResolveAll
();

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

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

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

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

那会吗?

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

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

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

Visual Studio中的程序集名称

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