2010-06-04 12 views
7

Tengo una aplicación de consola que transfiero a WPF. La aplicación tiene 3 subprocesos de trabajo, que están todos unidos al subproceso principal antes de que se impriman algunos resultados de salida en la pantalla. Según tengo entendido, si intento hacer lo mismo en una aplicación WPF, la GUI se bloqueará y no responderá al usuario. ¿Cómo puedo notificar al hilo padre que todos los hilos han completado su trabajo? Creo que la solución implicará delegados y eventos (¿o quizás BackgroundWorker?), Pero no me quedó claro cómo obtener la devolución de llamada invocada cuando finalizó el hilo.¿Cómo notifica a un hilo principal que todos los hilos hijo han terminado?

Código original:

foreach (Thread t in threadList) 
{ 
       t.Start(); 
} 

foreach (Thread t in threadList) 
{ 
       t.Join(); 
} 

// print some results here 

Respuesta

6

Si está utilizando tres BackgroundWorker s, se puede utilizar el evento RunWorkerCompleted darse cuenta de que uno de los trabajadores se ha completado: Antes de iniciar los trabajadores establece un contador de 3 a continuación, disminuir y comprobar este contador en el método llamado por RunWorkerCompleted si llega a 0 has terminado.

1

Tome un vistazo a este article en la revista de MSDN que proporciona un ejemplo sobre el uso de BackgroundWorker. Comience en la Figura 7.

3

Debe usar tres BackgroundWorkers.

A continuación, puede controlar sus eventos RunWorkerCompleted para averiguar cuándo finalizan las operaciones.

0

Si lo que desea es sondear los subprocesos de trabajo, podría utilizar algo así como bool threadWasDone = thread.Join(0);

1

Depende de lo que le gustaría lograr. ¿Qué tipo de comunicación estás tratando de facilitar?

Si tuviera que adivinar, lo que realmente desea es simplemente informar [o mostrar] los resultados de su trabajador en su aplicación. Si este es el caso, entonces en una aplicación típica de WPF tiene un modelo de vista, digamos

public class AwesomeViewModel : INotifyPropertyChanged 
{ 
    // if small fixed number, otherwise, you could use 
    // an ObservableCollection<T> 
    public string WorkerResultA { ... } 
    public string WorkerResultB { ... } 
    public string WorkerResultC { ... } 
} 

que está enlazada a datos a los controles de WPF. Simplemente puede pasar una referencia de su modelo de vista a cada subproceso de trabajo y actualizar la clase sin requerir bloqueo \ esperando en el subproceso de Gui. De esta manera, cada trabajador informa sus resultados cuando se completa sin la intervención de nadie más. Esto es óptimo.

Por supuesto, si continúas y haces solo esto, you run into another completely different issue. Que, fyi, se puede resolver a través de Dispatcher. One possible solution here.

En cuanto a BackgroundWorker frente al control Thread explícito, eso depende de usted. Hay ventajas para ambos, pero recuerde que ya tiene un código funcional escrito. Eso, y en mi opinión personal, BackgroundWorker no es particularmente útil.

Si realmente absolutamente positivamente debe implementar un modelo más sofisticado de sincronización, entonces le recomiendo que poner al día su primo ManualResetEventAutoResetEvent, Semaphore, palabra clave lock y programación concurrente en general. Lo sentimos, no hay atajos allí :)

Espero que esto ayude!

Cuestiones relacionadas