Saya dapat melihat 5 opsi yang tersedia:
1. Utas. Gabung
Seperti jawaban Mitch. Tapi ini akan memblokir utas UI Anda, namun Anda mendapatkan Timeout bawaan untuk Anda.
2. Gunakan a WaitHandle
ManualResetEvent
adalah WaitHandle
seperti yang disarankan jrista.
Satu hal yang perlu diperhatikan adalah jika Anda ingin menunggu beberapa utas, WaitHandle.WaitAll()
tidak akan berfungsi secara default, karena membutuhkan utas MTA. Anda dapat menyiasatinya dengan menandai Main()
metode Anda dengan MTAThread
- namun ini memblokir pompa pesan Anda dan tidak direkomendasikan dari apa yang saya baca.
3. Menembak sebuah acara
Lihat halaman ini oleh Jon Skeet tentang acara dan multi-threading, ada kemungkinan bahwa suatu peristiwa dapat menjadi tidak bertuliskan antara if
dan EventName(this,EventArgs.Empty)
- itu terjadi pada saya sebelumnya.
(Semoga kompilasi ini, saya belum mencoba)
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. Gunakan delegasi
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();
}
}
}
Jika Anda menggunakan metode _count, mungkin ide (agar aman) untuk menambahkannya menggunakan
Interlocked.Increment(ref _count)
Saya tertarik untuk mengetahui perbedaan antara menggunakan delegasi dan acara untuk pemberitahuan utas, satu-satunya perbedaan yang saya tahu adalah acara disebut serempak.
5. Sebagai gantinya, lakukan secara asinkron
Jawaban atas pertanyaan ini memiliki deskripsi yang sangat jelas tentang opsi Anda dengan metode ini.
Delegasi / Acara di utas yang salah
Cara event / delegate melakukan sesuatu akan berarti metode event handler Anda ada di thread1 / thread2 bukan utas UI utama , jadi Anda harus beralih kembali tepat di atas metode HandleThreadDone:
// Delegate example
if (InvokeRequired)
{
Invoke(new Action(HandleThreadDone));
return;
}