2011-02-04 10 views
19

W mojej aplikacji muszę pokazać formularz na kliknięcie myszą. Problem polega na tym, że formularz znajduje się w innym zespole, a z powodu leniwego charakteru ładowania zespołu prawdopodobnie zespół nie jest jeszcze załadowany po naciśnięciu przycisku myszy. Więc to, co mam, jest bardzo zauważalną pauzą, zanim wreszcie pojawi się formularz.Dobry sposób na wstępne ładowanie .NET assembly

Udało mi się wymyślić durną poprawkę, wywołując new FormFromAnotherAssembly() w mojej metody inicjalizacji. To oczywiście zajęło się sprawami i nie ma już przerwy, ale jest bardzo brzydka. Jedyne, co podoba mi się w tym rozwiązaniu, to że nie muszę zadzierać ścieżkami i nazwami zespołów, które muszę zrobić, jeśli chcę użyć czegoś takiego jak Assembly.Load.

Jakie jest dobre i niezawodne rozwiązanie, jeśli chcę się upewnić, że zespół został załadowany, zanim faktycznie go potrzebuję?

Z góry dziękuję.

+0

Odrzucasz dobre rozwiązanie. Jedynym innym jest uzyskanie szybszego dysku twardego. Jeśli nie defragged dysku w ciągu ostatnich 6 miesięcy, to teraz jest dobry czas. –

+0

@Hans Passant: który? – Dyppl

Odpowiedz

19

Jawne wstępne ładowanie w init jest prawdopodobnie najlepszą opcją.

a typeof(SomeTypeFromAnotherAssembly) powinno wystarczyć - wraz z pewną nieprzejrzystą metodą, której nie można zoptymalizować; być może:

GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly)); 

To pozwala uniknąć new. Zauważ, że to będzie ładowane, ale nie JITted itp

Jeśli chcesz, możesz to zrobić na nitce BG:

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

Dziękuję Marc, ale co, jeśli chcę, żeby był załadowany i zepsuty itp.? Ponieważ wygląda na to, że ładowanie zespołu jest tylko częścią problemu, a pauza wciąż tam jest. – Dyppl

+0

@Dyppl - JIT jest względnie szybki - sugeruję, aby problem polegał na ładowaniu * innych * (downstreamowych) zespołów i ładowaniu innych zasobów. Jeśli debugujesz, powinieneś być w stanie zobaczyć, co jeszcze ładuje ... –

+0

Cóż, tak, niestety, formularz jest z WPF i ciągnie dużo bzdur wraz z nim. – Dyppl

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

Czy to wystarczy?

+2

To jest to, co nazywam "zakłóceniami ze ścieżkami i nazwami zespołów", więc nie, nie zadziała – Dyppl

+0

Zawsze będzie działać tak długo, jak zespoły będą w tym samym folderze. Więc nie uważam tego za zepsucie. – jgauffin

+0

Co więcej, nie ma ich w tym samym folderze. – Dyppl

2

wierzę, że Assembly.Load jest droga.

Podczas uruchamiania aplikacji należy zlokalizować moduły, wtyczki lub inne moduły wykonawcze, które można podłączyć i załadować ich złożenia do domeny aplikacji (AppDomain).

Lub inna i lepsza opcja: Dlaczego nie używasz do tego odwrócenia kontroli?

Możesz użyć do tego Castle Windsor. Załóżmy, że masz 4 formularze do załadowania w czasie wykonywania, więc możesz utworzyć 4 komponenty klasy Form, których implementacja to 4 formularze do załadowania podczas cyklu życia twojego programu.

Jak wstępnie załadować to podejście? Po prostu rozwiązać wszystkie zależności/komponentów, które są typu formy i masz go:

container.ResolveAll<Form>(); 

Później dostaniesz żadnej szczególnej formy:

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

Jeśli nie wiesz odwrócenie sterowania , skomentuj, a ja ci pomogę, nie ma problemu! :)

+0

To wygląda trochę jak overkill do mojego problemu, ale dzięki – Dyppl

+0

Dobrze, że jeśli będziemy mieli dużo run-time załadowanych formach. Jeśli to nie jest sytuacja, tak, to jest dla ciebie przesada. –

+0

Cóż, w tej chwili jest to mało prawdopodobne, ale dziękuję i tak, wypróbuję twoje rozwiązanie, kiedy będę miał taką potrzebę. – Dyppl

0

Myślę, że najłatwiej jest po prostu użyć nazwy zespołu w Assembly.Load():

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

można znaleźć nazwę zespołu na podstawie właściwości odniesienia w Visual Studio:

assembly name in visual studio

W ten sposób można uniknąć wprowadzając ścieżki plików dll itd. Używam tego do prędkości do ładowania okna dialogowego korzystającego z tej biblioteki DLL. Gdy tylko główne okno programu zostanie w pełni załadowane, uruchamia wątek tła, który wywołuje funkcję Assembly.Load(). Gdy użytkownik otworzy to okno dialogowe, zniknie małe opóźnienie ładowania tej biblioteki DLL.

Powiązane problemy