Architettura corretta per l'esecuzione e l'arresto di attività complesse in background

0

Ho problemi a elaborare l'architettura corretta per la seguente attività. Ho una GUI in Windows Form che contiene un ListBox , che elenca alcuni layout architettonici. Un elemento in questo elenco è selezionato, un% personalizzatoControl visualizza una visualizzazione interattiva del layout selezionato. Il disegno di questo diagramma interattivo è un compito che richiede molta CPU e può richiedere fino a un secondo sulla mia macchina.

Il tipo di funzionalità che sto cercando di ottenere è che se un utente desidera scorrere rapidamente i layout in ListBox (ad esempio, tenendo premuto il tasto freccia giù), non voglio che il mio computer sieda Pensando a come disegnare il layout prima che consenta all'utente di fare qualsiasi altra cosa.

Ovviamente la risposta è, ovviamente, per eseguire i calcoli del layout in un thread separato. Ma come faccio a rendere quel thread un controllo completo? Come faccio a essere sicuro di non eseguire due calcoli di layout contemporaneamente?

Sono abbastanza nuovo in questa complessa attività della GUI. Quindi la vera domanda è qual è l'architettura giusta per implementare qualcosa di simile? Sembra che le persone lo facciano sempre, ma trovare qualche suggerimento su come farlo correttamente è davvero difficile.

    
posta Phonon 29.04.2011 - 17:59
fonte

3 risposte

2

Come ha detto Steve Townsend, la chiave qui è BackgroundWorker .

Poiché il tuo assistente in background è colui che disegna qualcosa sullo schermo devi nascondere il controllo che viene disegnato dalla vista finché non è finito. Per farlo disegnerei il contenuto su un controllo nascosto costruito dinamicamente e lo mostro solo quando:

  • l'operatore in background ha terminato
  • (facoltativamente) la voce selezionata nella casella di riepilogo è correlata all'operatore che ha terminato (per gestire la concorrenza)

Quindi quando una voce è selezionata nella casella di riepilogo:

  • Crea un lavoratore correlato alla voce, l'operatore dovrebbe eseguire il suo lavoro su un controllo nascosto.
  • Aggiungi metodi per l'ascolto di DoWork e RunWorkerCompleted . Il primo per iniziare il tuo disegno, il secondo per quando il disegno è finito.
  • Tentare di cancellare altri lavoratori che non hanno ancora finito chiamando CancelAsync su di essi
  • Avvia il worker chiamando RunWorkerAsync ()
  • OnRunWorkerCompleted - > Nascondere il controllo visualizzato in precedenza, mostrare il nuovo controllo su cui è stato disegnato l'operatore.

Inoltre, se la tua casella di riepilogo non è una casella di riepilogo a discesa, dovresti aggiungere un ritardo (ad esempio 0,2 s) al metodo che ascolta le modifiche nella casella di riepilogo per evitare di avviare i lavoratori troppo velocemente e quando non necessario.

Spero che ti aiuti!

    
risposta data 29.07.2011 - 10:38
fonte
1

Se ho capito bene, il tuo caso d'uso è proprio come una cartella con molti file e un pannello di anteprima, e vuoi che se l'utente scorre l'elenco, possa farlo senza problemi, senza aspettare che l'anteprima sia completamente visualizzato prima di spostare il cursore sul file successivo.

Non vedo molta architettura qui coinvolta. Devi scrivere un gestore per i movimenti del cursore e ad ogni tasto premere per interrompere il rendering del file precedente, se esiste, e avviare il rendering del file corrente.

    
risposta data 29.07.2011 - 09:52
fonte
0

Dai un'occhiata a BackgroundWorker per la tua attività di lunga durata. Assicurati di farlo solo una volta richiede una sorta di sincronizzazione tra thread: una bandiera con lock() su di essa, per esempio.

    
risposta data 29.04.2011 - 22:30
fonte

Leggi altre domande sui tag