Tôi có thể thấy 5 tùy chọn có sẵn:
1. Chủ đề.
Như với câu trả lời của Mitch. Nhưng điều này sẽ chặn luồng UI của bạn, tuy nhiên bạn sẽ có Thời gian chờ tích hợp sẵn cho bạn.
2. Sử dụng một WaitHandle
ManualResetEvent
là một WaitHandle
như jrista đề nghị.
Một điều cần lưu ý là nếu bạn muốn đợi nhiều luồng, WaitHandle.WaitAll()
sẽ không hoạt động theo mặc định, vì nó cần một luồng MTA. Bạn có thể khắc phục điều này bằng cách đánh dấu Main()
phương pháp của mình bằng MTAThread
- tuy nhiên điều này chặn bơm tin nhắn của bạn và không được đề xuất từ những gì tôi đã đọc.
3. Bắn một sự kiện
Xem trang này của Jon Skeet về các sự kiện và đa luồng, có thể một sự kiện có thể trở nên không được mô tả giữa if
và EventName(this,EventArgs.Empty)
- nó đã xảy ra với tôi trước đây.
(Hy vọng những biên dịch này, tôi chưa thử)
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. Sử dụng một đại biểu
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();
}
}
}
Nếu bạn sử dụng phương thức _count, có thể là một ý tưởng (để an toàn) để tăng nó bằng cách sử dụng
Interlocked.Increment(ref _count)
Tôi muốn biết sự khác biệt giữa việc sử dụng các đại biểu và sự kiện cho thông báo luồng, sự khác biệt duy nhất tôi biết là các sự kiện được gọi là đồng bộ.
5. Thay vào đó hãy thực hiện không đồng bộ
Câu trả lời cho câu hỏi này có một mô tả rất rõ ràng về các lựa chọn của bạn với phương pháp này.
Đại biểu / Sự kiện trên chuỗi sai
Cách làm việc của sự kiện / ủy nhiệm sẽ có nghĩa là phương thức xử lý sự kiện của bạn nằm trên thread1 / thread2 không phải là luồng UI chính , vì vậy bạn sẽ cần phải quay lại ngay ở đầu các phương thức HandleThreadDone:
// Delegate example
if (InvokeRequired)
{
Invoke(new Action(HandleThreadDone));
return;
}