多线程编程学习系列之--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采用的是内核时间模式,所以等待的时间不能太长。

发布了37 篇原创文章 · 获赞 3 · 访问量 6329

猜你喜欢

转载自blog.csdn.net/huan13479195089/article/details/88955291