2011-02-04 93 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的小滯後消失了。