ฉันเห็นตัวเลือก 5 ตัวเลือก:
1. ด้ายเข้าร่วม
เช่นเดียวกับคำตอบของมิทช์ แต่สิ่งนี้จะบล็อกเธรด UI ของคุณอย่างไรก็ตามคุณจะได้รับไทม์เอาต์ในตัวสำหรับคุณ
2. ใช้ WaitHandle
ManualResetEvent
เป็นWaitHandle
เป็น jrista ปัญหา
สิ่งหนึ่งที่ควรทราบคือถ้าคุณต้องการรอหลายเธรดWaitHandle.WaitAll()
จะไม่ทำงานตามค่าเริ่มต้นเนื่องจากต้องใช้เธรด MTA คุณสามารถแก้ไขปัญหานี้ได้โดยทำเครื่องหมายMain()
วิธีการของคุณด้วยMTAThread
- อย่างไรก็ตามสิ่งนี้จะบล็อกปั๊มข้อความของคุณและไม่แนะนำจากสิ่งที่ฉันอ่าน
3. เริ่มเหตุการณ์
ดูหน้านี้โดย Jon Skeetเกี่ยวกับกิจกรรมและมัลติเธรดอาจเป็นไปได้ว่าเหตุการณ์หนึ่งอาจไม่สามารถอธิบายได้ระหว่าง- if
และEventName(this,EventArgs.Empty)
- มันเคยเกิดขึ้นกับฉันมาก่อน
(หวังว่ารวบรวมเหล่านี้ฉันไม่ได้ลอง)
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. ใช้ผู้รับมอบสิทธิ์
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();
}
}
}
หากคุณใช้เมธอด _count อาจเป็นความคิด (เพื่อความปลอดภัย) เพื่อเพิ่มโดยใช้
Interlocked.Increment(ref _count)
ฉันสนใจที่จะทราบความแตกต่างระหว่างการใช้ผู้ได้รับมอบหมายและกิจกรรมสำหรับการแจ้งเตือนเธรดความแตกต่างเดียวที่ฉันรู้คือเหตุการณ์จะถูกเรียกพร้อมกัน
5. ทำแบบอะซิงโครนัสแทน
คำตอบสำหรับคำถามนี้มีคำอธิบายที่ชัดเจนเกี่ยวกับตัวเลือกของคุณด้วยวิธีนี้
มอบหมาย / เหตุการณ์บนเธรดที่ไม่ถูกต้อง
วิธีการจัดกิจกรรม / ผู้รับมอบสิทธิ์จะหมายถึงวิธีการจัดการเหตุการณ์ของคุณอยู่ใน thread1 / thread2 ไม่ใช่เธรด UI หลักดังนั้นคุณจะต้องสลับกลับไปที่ด้านบนสุดของวิธีการ HandleThreadDone:
// Delegate example
if (InvokeRequired)
{
Invoke(new Action(HandleThreadDone));
return;
}