2010-10-06 24 views
11

Sto refactoring il mio programma per utilizzare Parallel.ForEach. Prima, quando usavo un ciclo for normale, stavo aggiornando una barra di avanzamento WPF usando Dispatcher, visualizzando la% completata dividendo l'indice dell'array corrente per la dimensione dell'array. Con un ciclo foreach parallelo questo non viene visualizzato correttamente, ovvero il% salta in modo erotico, il che è previsto.Monitorare i progressi quando si utilizza Parallel.ForEach

Come è possibile aggiornare una barra di avanzamento WPF da un parallelo per ciascun ciclo in modo da poter tenere traccia del numero di iterazioni completate?

risposta

9

Come SLaks suggerisce, si dovrebbe incrementare il valore barra di avanzamento, invece di impostandolo sull'indice corrente ottenuto dal metodo Parallel.For.

Tuttavia, prenderei seriamente in considerazione l'utilizzo di un metodo meno costoso rispetto all'invio di un messaggio al thread dell'interfaccia utente a ogni iterazione .Se si dispone di un numero elevato di iterazioni, quindi inviare un messaggio ad ogni iterazione potrebbe essere molto impegnativo. Puoi dichiarare una variabile locale count d utilizzare Interlocked.Increment per incrementare la variabile in modo sicuro nel corpo del loop parallelizzato.

  • Allora si potrebbe usare qualcosa come if (count % 10 == 0) // ... per aggiornare la GUI solo dopo 10 iterazioni. (Questo non è completamente corretto, poiché altri thread potrebbero aggiornare count prima di controllare, ma se è solo per lo scopo della notificazione della GUI, allora non dovrebbe importare - non si vuole assolutamente usare lock nel corpo del loop).

  • In alternativa, è possibile creare un timer che verifichi ripetutamente il valore di count dal thread della GUI e aggiorni la barra di avanzamento. Questo è forse ancora più semplice e puoi garantire che la barra di avanzamento venga aggiornata abbastanza spesso, ma non di più.

4

Ogni volta che hai finito di un'operazione, si dovrebbe inviare un messaggio al thread UI (chiamando Dispatcher.BeginInvoke che incrementa la barra di avanzamento di 1.

Problemi correlati