2009-02-03 11 views
9

Ho problemi con qualcosa che voglio fare. Ho alcune grandi forme che richiedono del tempo per creare. Per far sì che l'app si carichi più velocemente ho pensato di lasciare che i moduli venissero creati in un thread creato nell'evento OnCreate della form principale. Il thread ha un campo di applicazione di tipo TApplication che ovviamente è la variabile Application. Io uso che per creare i moduli sul filo, ma anche comunque ho provatoCreazione modulo Delphi senza congelamento filo principale

FApplication.CreateForm (TfrmXXX, frmXXX) 

e

frmXXX := TFrmXXX.Create(FApplication) 

forme ancora arent create. C'è qualche soluzione alternativa per questo ?

Grazie in anticipo.

risposta

26

La creazione di moduli in una discussione semplicemente non funzionerà. Il VCL, e in particolare la parte visiva, non è thread-safe. Rinuncia a questa idea e ottimizza invece il codice che sta causando un lungo processo di creazione del modulo. Non ci hai detto quale sia la parte lenta. Se puoi rispondere a questo, forse possiamo suggerire un metodo per accelerarlo.

In generale, non è possibile fare un buon lavoro per migliorare le prestazioni di un pezzo di codice finché non lo si profila e si conosce esattamente quale sia il problema. Altrimenti, stai solo perdendo tempo.

+1

In realtà, la creazione di una finestra in un thread diverso dal thread dell'interfaccia utente principale è un'idea completamente legittima in Win32 che ha i suoi usi. Questo non ha nulla a che fare con "VCL essere thread safe". Se voglio avere 3 thread ciascuno con il proprio ciclo di messaggi, perché dovrebbe preoccuparsi VCL? I loop del messaggio non dovrebbero parlare tra loro, sono in contesti separati (cioè nessun problema con la sicurezza del thread). –

+2

Milano, finestra Win32 <> modulo VCL. Vuole un modulo VCL e semplicemente non puoi farlo, non importa quanto tu voglia. –

6

La soluzione non sarà facile, come

  1. Delphi VCL non è thread safe
  2. finestre creando in un'altra filo richiede rispettivo filo di avere un ciclo di messaggi

Hai bisogno di tutti i moduli contemporaneamente? In caso contrario, è possibile rinviare la creazione a un'ora in cui l'applicazione è inattiva (ad esempio TApplicationEvents.OnIdle). Oppure mostra solo una bella barra di avanzamento :)

+0

Ho votato questa risposta per aver sottolineato che non è necessario creare tutti i moduli contemporaneamente, ma una barra di avanzamento mi farebbe salire al muro, come utente. :) –

+1

Sì, in fondo mi sento lo stesso. Ma se è inevitabile fare lunghe operazioni all'avvio, allora è meglio averne uno che non. Una volta mi sono dimenticato di mostrarlo e i clienti hanno interrotto l'app perché pensavano che si blocchino: -/Ma comunque - hai certamente ragione suggerendo un'ulteriore ottimizzazione. –

0

Non riesco a immaginare cosa ci vorrebbe così tanto tempo nella creazione di moduli che avrebbe bisogno di discussioni da risolvere. Se è un'enorme quantità di dati, cerca di limitare l'importo mostrato inizialmente.

4

Come sottolinea Riho, la creazione di moduli non dovrebbe richiedere tempo. Tuttavia, ciò che può richiedere del tempo è tutto il codice che hai inserito nel costruttore o l'evento OnCreate di quel modulo.

Indica il tuo codice, come suggerito da Craig, in modo da sapere quale codice occupa più tempo. Quindi vedi se puoi spostare parte di quel codice in un thread separato.

0

Questa è una scorciatoia che abbiamo usato prima per i moduli che hanno un sacco di processi da fare al momento della creazione. Rilascia un TTimer nel modulo e impostalo su false. OnCreate del modulo abilitarlo. Quindi inserisci tutto il codice che avevi in ​​OnCreate nell'evento OnTimer. L'impostazione dell'intervallo da 250 a 500 è sufficiente.

Questa non è una soluzione elegante, ma è semplice.

0

ci sono alcune grandi forme là fuori come ho detto prima. il file DFM è come 3mb (inclusi ovviamente i dati dell'immagine). In realtà penso che la maggior parte del tempo di creazione sia dovuto a quello piuttosto che al codice eseguito. Ma forse è difficile scomporle e crearle quando l'app è inattiva, il tempo di caricamento attuale non è molto grande (come 4 o 5 secondi), ma non lo guardo bene. grazie per le tue risposte

1

Come sopra, è necessario creare i moduli nel thread VCL. Ma, non c'è bisogno di fare tutto quello che c'è:

Se i moduli hanno un sacco di dati di immagine, è possibile rimuovere che dalle forme, e metterlo in un file di risorse (o semplicemente utilizzare i file di immagine RAW)

Nel costruttore del modulo, avviare un thread in background per leggere i dati dell'immagine dalle risorse e fare altre cose lente. Sovrascrivi l'evento OnShow dei moduli per assicurarti che il thread in background venga completato prima che venga visualizzato il modulo.

1

Basta inserire un PostMessage nei moduli OnCreate e avviare una procedura nel modulo per gestire il messaggio post. In questo modo, tutto il codice che richiede tempo può essere rimosso dal metodo OnCreate. Sono d'accordo però, creo il modulo solo quando è necessario, e quindi effettivamente implemento qualche logica per decidere se lo libererai da vicino, o meno .. A seconda del tempo di caricamento e della possibilità che l'utente lo vorrà di nuovo ..

Jens Fudge, Archersoft