多线程编程学习系列之--AutoResetEvent类
示例代码
//
private static AutoResetEvent _workerEvent = new AutoResetEvent(false);
private static AutoResetEvent _mainEvent = new AutoResetEvent(false);
static void Process(int seconds)
{
//输出顺序:2
Console.WriteLine("Starting a long running work...");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
//输出顺序:3
Console.WriteLine("Work is done!");
//发送信号,通知线程可以继续
_workerEvent.Set();
//输出顺序:4
Console.WriteLine("Waiting for a main thread to complete its work");
//阻止当前线程,直到接受到信号
_mainEvent.WaitOne();
//输出顺序:8
Console.WriteLine("Starting second opreation...");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
//输出顺序:9
Console.WriteLine("Work is done");
//发送信号,通知线程可以继续
_workerEvent.Set();
}
static void Main(string[] args)
{
//开启一个线程
var t = new Thread(() => Process(10));
t.Start();
//输出顺序:1
Console.WriteLine("Waiting for another thread to complete work");
//阻止当前线程,直到接受到信号
_workerEvent.WaitOne();
//输出顺序:5
Console.WriteLine("First opreation is completed!");
//输出顺序:6
Console.WriteLine("Performing an operation on a main thread");
Thread.Sleep(TimeSpan.FromSeconds(5));
//发送信号,通知线程可以继续
_mainEvent.Set();
//输出顺序:7
Console.WriteLine("Now running the second operation on a second thread");
//阻止当前线程,直到接受到信号
_workerEvent.WaitOne();
//输出顺序:10
Console.WriteLine("Second opreation is completed!");
Console.ReadKey();
}
结果
原理
定义了两个AutoResetEvent实例,一个是子线程往主线程发送信号,一个是主线程往子线程发送信号,构造方法传入false,初始状态为unsignaled,意味着任何线程调用两个对象的WaitOne方法都会阻塞线程,直到我们调用了Set方法。如果我们初始设为true,那么线程调用WaitOne会立即处理,状态变为unsignaled,需要重新Set以便其他线程使用。然后我们创建了两个线程,其会执行第一个操作10秒,然后等待从第二个线程发出的信号,该信号意味着第一个操作已经完成。现在第二个线程等待主线程的信号,我们对主线程做了附加工作,并通过调用_mainEvent.Set();发出信号,然后等待第二个线程发出的另一个信号。
AutoResetEvent采用的是内核时间模式,所以等待的时间不能太长。