预加载.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
如果您不知道控制倒置,请注释掉,我会帮助您,没问题! 🙂
var yourAppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); Assembly.Load(Path.Combine(yourAppPath, "formAssembly.dll"));
那会吗?
我认为最简单的方法是在Assembly.Load()中使用程序集名称:
System.Reflection.Assembly.Load("ICSharpCode.AvalonEdit");
您可以在Visual Studio中的引用属性下找到程序集名称:
这样您就可以避免输入dll文件路径等。我使用它来加速加载使用此DLL的对话框。 一旦程序主窗口完全加载,它就会启动一个只调用Assembly.Load()的后台线程。 当用户打开此对话框时,加载此DLL的小延迟消失了。