Posso vedere 5 opzioni disponibili:
1. Thread.Join
Come con la risposta di Mitch. Ma questo bloccherà il tuo thread dell'interfaccia utente, tuttavia ottieni un Timeout integrato per te.
2. Utilizzare a WaitHandle
ManualResetEvent
è un WaitHandle
jrista come suggerito.
Una cosa da notare è se vuoi aspettare più thread, WaitHandle.WaitAll()
non funzionerà di default, poiché ha bisogno di un thread MTA. Puoi aggirare questo contrassegnando il tuo Main()
metodo con MTAThread
- tuttavia questo blocca il tuo pump dei messaggi e non è raccomandato da quello che ho letto.
3. Attiva un evento
Vedi questa pagina di Jon Skeet su eventi e multi-threading, è possibile che un evento possa essere cancellato tra il if
e il EventName(this,EventArgs.Empty)
- è successo a me prima.
(Spero che questi compilano, non ho provato)
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. Utilizzare un delegato
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();
}
}
}
Se si utilizza il metodo _count, potrebbe essere un'idea (per sicurezza) incrementarlo utilizzando
Interlocked.Increment(ref _count)
Sarei interessato a conoscere la differenza tra l'utilizzo di delegati ed eventi per la notifica di thread, l'unica differenza che conosco sono gli eventi chiamati in modo sincrono.
5. Fallo invece in modo asincrono
La risposta a questa domanda ha una descrizione molto chiara delle tue opzioni con questo metodo.
Delegato / Eventi sul thread errato
Il modo evento / delegato di fare le cose significherà che il tuo metodo del gestore eventi è su thread1 / thread2 non sul thread dell'interfaccia utente principale , quindi dovrai tornare indietro nella parte superiore dei metodi HandleThreadDone:
// Delegate example
if (InvokeRequired)
{
Invoke(new Action(HandleThreadDone));
return;
}