在我的应用中,我需要在鼠标点击时显示一个表单。问题是表单在另一个程序集中,并且由于程序集加载的惰性,很可能在按下鼠标按钮时尚未加载程序集。因此,在表单最终出现之前,我所拥有的是非常明显的暂停。
通过在初始化方法中调用new FormFromAnotherAssembly()
,我能够提出一个愚蠢的修复方法。那当然是照顾好事情,停顿不再存在,但它非常难看。我唯一喜欢这个解决方案的是,如果我想使用类似Assembly.Load
的东西,我不必弄乱路径和汇编名称。
那么,如果我想确保在实际需要之前加载程序集,那么选择好的,强大的解决方案是什么?
提前致谢。
答案 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)