Nunca antes he usado subprocesos en C # donde necesito tener dos subprocesos, así como el subproceso principal de la interfaz de usuario. Básicamente, tengo lo siguiente.
public void StartTheActions()
{
//Starting thread 1....
Thread t1 = new Thread(new ThreadStart(action1));
t1.Start();
// Now, I want for the main thread (which is calling `StartTheActions` method)
// to wait for `t1` to finish. I've created an event in `action1` for this.
// The I wish `t2` to start...
Thread t2 = new Thread(new ThreadStart(action2));
t2.Start();
}
Entonces, esencialmente, mi pregunta es cómo hacer que un hilo espere a que termine otro. ¿Cuál es la mejor manera de hacer esto?
c#
multithreading
Maxim Zaslavsky
fuente
fuente
Respuestas:
Puedo ver 5 opciones disponibles:
1. Hilo. Únete
Como con la respuesta de Mitch. Pero esto bloqueará su hilo de interfaz de usuario, sin embargo, obtendrá un tiempo de espera incorporado para usted.
2. Use un
WaitHandle
ManualResetEvent
esWaitHandle
como sugirió jrista.Una cosa a tener en cuenta es que si desea esperar varios subprocesos,
WaitHandle.WaitAll()
no funcionará de forma predeterminada, ya que necesita un subproceso MTA. Puede evitar esto marcando suMain()
método conMTAThread
, sin embargo, esto bloquea su mensaje y no es recomendable por lo que he leído.3. Dispara un evento
Vea esta página de Jon Skeet sobre eventos y subprocesos múltiples, es posible que un evento pueda quedar sin suscripción entre el
if
y elEventName(this,EventArgs.Empty)
- me ha sucedido antes.(Ojalá estas compilación, no lo he probado)
4. Use un delegado
Si usa el método _count, podría ser una idea (para estar seguro) incrementarlo usando
Interlocked.Increment(ref _count)
Me interesaría saber la diferencia entre usar delegados y eventos para la notificación de subprocesos, la única diferencia que sé es que los eventos se llaman sincrónicamente.
5. Hazlo asincrónicamente
La respuesta a esta pregunta tiene una descripción muy clara de sus opciones con este método.
Delegado / Eventos en el hilo equivocado
La forma de hacer eventos / delegar significará que su método de controlador de eventos está en thread1 / thread2 no en el hilo principal de la interfaz de usuario , por lo que deberá volver a la derecha en la parte superior de los métodos HandleThreadDone:
fuente
Añadir
después de iniciarlo, ¡pero eso no logrará mucho, ya que es esencialmente el mismo resultado que ejecutar en el hilo principal!
Puedo recomendar leer el libro electrónico gratuito Threading in C # de Joe Albahari , si desea obtener una comprensión de los hilos en .NET.
fuente
Join
es literalmente lo que parece haber pedido el autor de la pregunta, en general puede ser extremadamente malo. Una llamada aJoin
colgará el hilo desde el que se está haciendo esto. Si ese es el hilo principal de la GUI, ¡es MALO ! Como usuario, detesto activamente las aplicaciones que parecen funcionar de esta manera. Así que por favor vea todas las otras respuestas a esta pregunta y stackoverflow.com/questions/1221374/…Las dos respuestas anteriores son geniales y funcionarán para escenarios simples. Sin embargo, hay otras formas de sincronizar hilos. Lo siguiente también funcionará:
ManualResetEvent es uno de los diversos WaitHandle que ofrece .NET Framework. Pueden proporcionar capacidades de sincronización de subprocesos mucho más ricas que las herramientas simples pero muy comunes como lock () / Monitor, Thread.Join, etc. También se pueden usar para sincronizar más de dos subprocesos, lo que permite escenarios complejos como un subproceso 'maestro' que coordina múltiples subprocesos 'secundarios', múltiples procesos concurrentes que dependen de varias etapas entre sí para sincronizarse, etc.
fuente
Si utiliza desde .NET 4, este ejemplo puede ayudarlo a:
de: https://stackoverflow.com/a/4190969/1676736
fuente
Desea el
Thread.Join()
método, o una de sus sobrecargas .fuente
Quisiera que su hilo principal pase un método de devolución de llamada a su primer hilo, y cuando termine, invocará el método de devolución de llamada en el hilo principal, que puede iniciar el segundo hilo. Esto evita que su hilo principal se cuelgue mientras espera un Join o Waithandle. Pasar métodos como delegados es algo útil para aprender con C # de todos modos.
fuente
Prueba esto:
fuente
Posiblemente para ayudar a otros, pasé bastante tiempo buscando una solución como la que se me ocurrió. Entonces tomé un enfoque un poco diferente. Hay una opción de contador arriba, solo la apliqué un poco diferente. Estaba hilando numerosos hilos e incrementé un contador y disminuí un contador cuando un hilo comenzó y se detuvo. Luego, en el método principal, quería pausar y esperar a que se completaran los hilos que hice.
Documentado en mi blog. http://www.adamthings.com/post/2012/07/11/ensure-threads-have-finished-before-method-continues-in-c/
fuente
Cuando quiero que la IU pueda actualizar su pantalla mientras espero que se complete una tarea, uso un ciclo while que prueba IsAlive en el hilo:
fuente
Aquí hay un ejemplo simple que espera a que termine una banda de rodadura, dentro de la misma clase. También realiza una llamada a otra clase en el mismo espacio de nombres. Incluí las declaraciones de "uso" para que pueda ejecutarse como Winform siempre que cree el botón1.
fuente