2009-02-14 10 views
7

Al lavoro utilizziamo DevExpress per l'interfaccia utente. La prima volta che viene aperto un modulo che utilizza un controllo DevExpress c'è una lunga pausa (a volte 15-20 secondi su alcuni client). In Visual Studio posso vedere che tonnellate di assiemi vengono caricati durante questa fase. C'è un modo per precaricare gli assembly in AppDomain in background su un thread che viene generato ad esempio prima che venga visualizzata la schermata di login?Precaricamento gruppi

risposta

0

dai un'occhiata ai metodi Assembly.oad.

Gero

2

Ciò tuttavia imporre agli utenti di prendere sempre quel colpo in fase di start up.

In generale questa è una cattiva idea (se si ha almeno il successo, differire fino a quando ne hai davvero bisogno). Un caso in cui potrebbe essere d'aiuto è di innescare il carico se c'è una forte possibilità che siano andando a per utilizzare la funzionalità nel prossimo futuro ma il sistema è altrimenti inattivo. Questo può essere molto difficile da fare con precisione.

È possibile vedere se uno qualsiasi degli assembly caricati è sotto il proprio controllo e nel GAC. In tal caso, potresti annullarli, il che potrebbe avere un effetto significativo sull'orario di avvio di questo aspetto dell'interfaccia utente.

+0

Sto pianificando di caricare gli assembly in un thread in background mentre l'utente digita il nome utente e la password, quindi non ci sarà nessun hit rilevante all'avvio. – Rauhotz

+0

Ci sarà a meno che: 1) Le DLL siano * sempre * richieste 2) Il tempo di caricamento è molto vicino o inferiore al tempo necessario per l'accesso. Se questi sono entrambi veri questo può essere utile ... – ShuggyCoUk

1

Non sono sicuro, ma suppongo che il caricamento effettivo degli assembly non sia la parte relativa al tempo, ma probabilmente la compilazione JIT del percorso del codice. Forse vuoi guardare ngen. potrebbe essere che fa andare via il problema delle prestazioni. ma sii sicuro di capire le implicazioni di quello strumento.

vicini: - http://msdn.microsoft.com/en-us/library/6t9t5wcf.aspx - http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

+0

L'utilizzo della CPU è piuttosto basso durante la pausa. – Rauhotz

+0

Hmm, proverei comunque a precompilare con ngen. Abbandonano un sacco di ottimizzazione. Forse il costo di avvio va via. –

+0

non è tanto l'uso della CPU come il disco aggiuntivo che richiede. – ShuggyCoUk

4

Un'altra scelta è di forzare il JIT per caricare le assemblee asynchronious invece di farlo a mano. Il trucco è chiamare semplicemente il costruttore del controllo, quindi il Jit sa che deve iniziare a compilare quel particolare percorso di codice. Di solito questo lo costringe a caricare tutti gli assembly dipendenti. Assicurati di racchiudere la chiamata del costruttore da un tentativo di cattura.

Un esempio di come farlo in loadtime:

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     PreJitControls(); 

     Application.Run(new Form1()); 
    } 

    private static void PreJitControls() 
    {   
     ThreadPool.QueueUserWorkItem((t) => 
     { 
      Thread.Sleep(1000); // Or whatever reasonable amount of time 
      try 
      { 
       AssemblyPullingControl1 c = new AssemblyPullingControl1(); 
      } 
      catch (Exception) { } 

      try 
      { 
       AssemblyPullingControl2 c = new AssemblyPullingControl2(); 
      } 
      catch (Exception) { } 

     }); 
    } 
} 

Ma si potrebbe anche fare qualcosa di simile nel costruttore del form di login, se questo è un momento migliore per fare il pre-caricamento. Basta spostare il metodo PreJitControls al modulo di accesso e chiamarlo dal costruttore.

0

Se si sta tentando di ottenere gli assembly più velocemente, perché non dare un'occhiata a NGEN per il codice. Pre JIT tutto sullo sfondo. Questo ha pro e contro a seconda di cosa sta facendo la tua app.