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
es WaitHandle
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 su Main()
método con MTAThread
, 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 el EventName(this,EventArgs.Empty)
- me ha sucedido antes.
(Ojalá estas compilación, no lo he probado)
public class Form1 : Form
{
int _count;
void ButtonClick(object sender, EventArgs e)
{
ThreadWorker worker = new ThreadWorker();
worker.ThreadDone += HandleThreadDone;
Thread thread1 = new Thread(worker.Run);
thread1.Start();
_count = 1;
}
void HandleThreadDone(object sender, EventArgs e)
{
// You should get the idea this is just an example
if (_count == 1)
{
ThreadWorker worker = new ThreadWorker();
worker.ThreadDone += HandleThreadDone;
Thread thread2 = new Thread(worker.Run);
thread2.Start();
_count++;
}
}
class ThreadWorker
{
public event EventHandler ThreadDone;
public void Run()
{
// Do a task
if (ThreadDone != null)
ThreadDone(this, EventArgs.Empty);
}
}
}
4. Use un delegado
public class Form1 : Form
{
int _count;
void ButtonClick(object sender, EventArgs e)
{
ThreadWorker worker = new ThreadWorker();
Thread thread1 = new Thread(worker.Run);
thread1.Start(HandleThreadDone);
_count = 1;
}
void HandleThreadDone()
{
// As before - just a simple example
if (_count == 1)
{
ThreadWorker worker = new ThreadWorker();
Thread thread2 = new Thread(worker.Run);
thread2.Start(HandleThreadDone);
_count++;
}
}
class ThreadWorker
{
// Switch to your favourite Action<T> or Func<T>
public void Run(object state)
{
// Do a task
Action completeAction = (Action)state;
completeAction.Invoke();
}
}
}
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:
// Delegate example
if (InvokeRequired)
{
Invoke(new Action(HandleThreadDone));
return;
}