ManualResetEvent(转)

ManualResetEvent 用于线程同步,通知一个或多个线程某事件已经发生。通常用于一个线程执行的任务必须在其他线程的任务执行之前完成。
ManualResetEvent状态分为两种:终止状态和非终止状态。当某一任务完成时,将ManualResetEvent设置为终止状态,这样其他等待的线程(一个或多个)将开始执行自己的任务。
注意:一旦它被终止,它将保持终止状态,直到它被手动重置。

代码示例:

public class AutoResetEventHelper
    {

        static void Main(string[] args)
        {
            Caclultae calc = new Caclultae();
            Console.WriteLine("Result={0}", calc.result(234).ToString());

            Console.Read();
        }


    }


    class Caclultae
    {
        double baseNum, firNum, secNum, thdNum;
        AutoResetEvent[] autoEvents;
        ManualResetEvent manualEvent;
        Random Generator;
        public Caclultae()
        {
            autoEvents = new AutoResetEvent[]
            {
                new AutoResetEvent(false),
               new AutoResetEvent(false),
                new AutoResetEvent(false)
            };
            manualEvent = new ManualResetEvent(false);
        }
        void CalBase(object stateInfo)
        {
            baseNum = Generator.NextDouble();
            Console.WriteLine("BaseNum is Ok");
            manualEvent.Set();
        }
        void CalFirst(object stateInfo)
        {
            double preCalc = Generator.NextDouble();

            manualEvent.WaitOne();
            Console.WriteLine("FirstNum begins to Calculate");
            firNum = preCalc * baseNum * Generator.NextDouble();

            autoEvents[0].Set();
            Console.WriteLine("FirstNum Calculates successfully");
        }
        void CalSec(object stateInfo)
        {
            double preCalc = Generator.NextDouble();
            manualEvent.WaitOne();
            Console.WriteLine("SecNum begins to Calculate");
            secNum = preCalc * baseNum * Generator.NextDouble();
            autoEvents[1].Set();
            Console.WriteLine("SecNum  Calculates successfully");
        }
        void CalThird(object stateInfo)
        {
            double preCalc = Generator.NextDouble();
            manualEvent.WaitOne();
            Console.WriteLine("ThrdNum begins to Calculate");
            thdNum = preCalc * baseNum * Generator.NextDouble();
            autoEvents[2].Set();
            Console.WriteLine("ThrdNum  Calculates successfully");
        }
        public double result(int seed)
        {
            Generator = new Random(seed);
            ThreadPool.QueueUserWorkItem(new WaitCallback(CalBase));
            ThreadPool.QueueUserWorkItem(new WaitCallback(CalFirst));
            ThreadPool.QueueUserWorkItem(new WaitCallback(CalSec));
            ThreadPool.QueueUserWorkItem(new WaitCallback(CalThird));
            WaitHandle.WaitAll(autoEvents);
            manualEvent.Reset();
            return firNum + secNum + thdNum;
        }

    }

代码中,我们可以看到,CalFirst,CalSec,CalThird都在等待CalBase执行完成。当CalBase计算出BaseNum的结果之后,将ManualResetEvent变量设置为终止状态,通知其他三个任务,可以执行他们自己的任务了。
执行结果:
1).执行一次的结果:
这里写图片描述

2). 再次执行的结果:
这里写图片描述
从两次执行结果中看出,CalFirst、CalSec、CalThird的执行顺序是不一定的,也就是说 这三个的地位是相同的,都在等待CalBase执行成功,从而执行自己的任务。这也验证了 ManualResetEvent的作用,用于通知一个或多个线程某个事件发生。

本文转自:
Thread系列——ManualResetEvent

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值