2011-02-04 97 views
19

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

我能够通过在我的初始化方法中调用new FormFromAnotherAssembly()来想出一个愚蠢的修复程序。当然,这照顾了事情,暂停不再存在,但这非常丑陋。我唯一喜欢这个解决方案的地方是,如果我想使用类似Assembly.Load的东西,我不必乱用路径和程序集名称。

那么,如果我想确保程序集在我真正需要之前就被加载了,那么选择什么样的好的,可靠的选择?

在此先感谢。

+0

你正在解雇一个好的解决方案。唯一的另一个是获得更快的硬盘。如果您在过去6个月内没有对磁盘进行碎片整理,那么现在是个好时机。 – 2011-02-04 09:16:17

+0

@Hans Passant:哪一个? – Dyppl 2011-02-04 09:29:06

回答

19

在您的init中显式预加载可能仍然是您的最佳选择。

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

GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly)); 

这可以避免new。请注意,这将是加载,但不是即时编译等

如果你愿意,你可以做一个BG螺纹:

private static void LoadSomeStuff(object state) { 
    GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly)); 
} 
... 
ThreadPool.QueueUserWorkItem(LoadSomeStuff); 
1
var yourAppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
Assembly.Load(Path.Combine(yourAppPath, "formAssembly.dll")); 

请问这样做?

+2

这就是我所说的“搞乱路径和程序集名称”,所以不,它不会做 – Dyppl 2011-02-04 08:06:58

+0

只要程序集位于同一个文件夹中,它就会一直工作。所以我不认为它是一团糟。 – jgauffin 2011-02-04 08:09:34

2

我相信Assembly.Load是这样的。

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

或另一个更好的选择:为什么你不使用控制倒置?

您可以使用Castle Windsor。假设你有4种形式要在运行时加载,所以,你可以创建4个Form类的组件,它们的实现就是你的程序生命周期中加载的4种形式。

如何使用此方法预加载?您只需解决的类型表的所有依赖/组件和你说对了:

container.ResolveAll<Form>(); 

后来你会得到一个特殊形式:

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

如果你不知道的控制反转,注释掉,我会协助你,没问题! :)

0

我认为最简单的方法就是在Assembly中使用程序集名称。负载():

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

您可以在Visual Studio中的参考属性中找到的组件名称:

assembly name in visual studio

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