Widzę 5 dostępnych opcji:
1. Thread.Join
Jak w przypadku odpowiedzi Mitcha. Ale to zablokuje twój wątek interfejsu użytkownika, jednak otrzymasz wbudowany limit czasu.
2. Użyj WaitHandle
ManualResetEvent
jest WaitHandle
jak sugerowała jrista.
Należy zwrócić uwagę na to, że jeśli chcesz czekać na wiele wątków, WaitHandle.WaitAll()
nie będzie działać domyślnie, ponieważ wymaga wątku MTA. Możesz to obejść, oznaczając swoją Main()
metodę znakiem MTAThread
- jednak blokuje to twoją pompę wiadomości i nie jest zalecane z tego, co przeczytałem.
3. Odpal wydarzenie
Zobacz tę stronę Jon Skeet o wydarzeniach i wielowątkowości, to możliwe, że zdarzenie może stać unsubcribed pomiędzy if
iEventName(this,EventArgs.Empty)
- zdarzyło mi się to wcześniej.
(Mam nadzieję, że te kompilacje, nie próbowałem)
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. Użyj pełnomocnika
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();
}
}
}
Jeśli używasz metody _count, może być pomysłem (ze względów bezpieczeństwa), aby ją zwiększyć za pomocą
Interlocked.Increment(ref _count)
Chciałbym poznać różnicę między używaniem delegatów a zdarzeniami do powiadamiania o wątkach, jedyną różnicą, jaką znam, jest to, że zdarzenia są wywoływane synchronicznie.
5. Zrób to asynchronicznie
Odpowiedź na to pytanie zawiera bardzo jasny opis możliwości tej metody.
Deleguj / Zdarzenia w niewłaściwym wątku
Sposób działania zdarzenia / delegata będzie oznaczał, że metoda obsługi zdarzeń znajduje się w wątku1 / wątku2, a nie w głównym wątku interfejsu użytkownika , więc będziesz musiał przełączyć się z powrotem na górę metod HandleThreadDone:
// Delegate example
if (InvokeRequired)
{
Invoke(new Action(HandleThreadDone));
return;
}