c# 多线程编程中AutoResetEvent和ManualResetEvent

作为等同于Java的wait,notify,notifyAll的存在,AutoResetEvent和ManualResetEvent分别实现了notify和notifyAll的功能,下面的代码简单讲解了一下实现原理,并展示了这一过程。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ThreadTest
{
    class Program
    {
        //新建一个默认无信号的手动重置线程事件
        private void Test()
        {
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            AutoResetEvent autoResetEvent = new AutoResetEvent(false);
            //线程传参需要通过ParameterizedThreadStart委托,并在Start时附加参数。
            new Thread(new ParameterizedThreadStart(MyThreadHandler)).Start(new ParamStruct("Thread1", manualResetEvent));
            new Thread(new ParameterizedThreadStart(MyThreadHandler)).Start(new ParamStruct("Thread2", manualResetEvent));
            new Thread(new ParameterizedThreadStart(MyThreadHandler)).Start(new ParamStruct("Thread3", autoResetEvent));
            new Thread(new ParameterizedThreadStart(MyThreadHandler)).Start(new ParamStruct("Thread4", autoResetEvent));
            Thread.Sleep(1000);
            //manualResetEvent在Set方法中,会让信号状态从无到有,从而让所有wait状态的线程唤醒,实现NotifyAll
            manualResetEvent.Set();
            //autoResetEvent在Set方法中,会在第一个处于wait状态的线程唤醒后将信号状态Reset,变为无信号,实现NotifyOne
            autoResetEvent.Set();
            Thread.Sleep(1000);
            autoResetEvent.Set();
            Console.ReadKey();
        }
        static void Main(string[] args)
        {
            new Program().Test();
        }
        private void MyThreadHandler(object obj)
        {
            if (obj is ParamStruct paramStruct)
            {
                Console.WriteLine(paramStruct.threadName);
                paramStruct.resetEvent.WaitOne();
                Console.WriteLine(paramStruct.threadName + " finished on " + DateTime.Now);
            }
        }
    }
    class ParamStruct
    {
        public string threadName;
        public EventWaitHandle resetEvent;
        public ParamStruct(string threadName, EventWaitHandle resetEvent)
        {
            this.threadName = threadName;
            this.resetEvent = resetEvent;
        }
    }
}
posted @ 2017-08-07 17:43  CieloSun  阅读(328)  评论(0编辑  收藏  举报