ManualResetEvent
是 C# 中的一個同步原語,它允許一個或多個線程等待,直到另一個線程設置一個事件。ManualResetEvent
的信號控制主要通過其 Set()
和 Reset()
方法來實現。
Set()
方法時,如果 ManualResetEvent
當前處于未信號狀態(即沒有線程在等待),則它會被設置為信號狀態。如果有線程正在等待,那么這些線程會立即被釋放并繼續執行。如果 ManualResetEvent
已經是信號狀態,那么調用 Set()
方法不會有任何效果。Reset()
方法時,ManualResetEvent
會被設置為非信號狀態。這意味著任何正在等待該事件的線程都會被阻塞,直到再次調用 Set()
方法將其設置為信號狀態。以下是一個簡單的示例,展示了如何使用 ManualResetEvent
來同步線程:
using System;
using System.Threading;
class Program
{
static ManualResetEvent _event = new ManualResetEvent(false); // 初始化為非信號狀態
static void Main()
{
Thread thread1 = new Thread(DoWork);
Thread thread2 = new Thread(DoWork);
thread1.Start();
thread2.Start();
// 讓線程1先執行
_event.Set();
thread1.Join();
thread2.Join();
}
static void DoWork()
{
Console.WriteLine("Thread is waiting for event...");
_event.WaitOne(); // 等待事件被設置為信號狀態
Console.WriteLine("Event received. Thread continues.");
}
}
在這個示例中,我們創建了兩個線程 thread1
和 thread2
,它們都調用 DoWork
方法。在 Main
方法中,我們首先啟動這兩個線程,然后調用 _event.Set()
來設置事件,使得 thread1
可以立即繼續執行。thread1
執行完畢后,主線程調用 Join()
等待兩個線程都執行完畢。
需要注意的是,ManualResetEvent
的信號狀態只能由一個線程來設置,其他線程必須等待該事件被設置后才能繼續執行。如果多個線程同時調用 Set()
方法,那么只有第一個調用的線程會成功設置事件狀態,其他線程會拋出異常。為了避免這種情況,可以使用 Monitor
或其他同步原語來確保只有一個線程能夠設置事件狀態。