AutoResetEvent和ManualResetEvent

这两个类都继承子 EventWaitHandle。并且可以直接使用EventWaitHandle,同时再构造时指定相应参数来决定实现

AutoResetEvent或者ManualEvent的功能。

在.Net多线程编程中,AutoResetEvent和ManualResetEvent这两个类经常用到, 他们的用法很类似,但也有区别。
Set方法将信号置为发送状态,Reset方法将信号置为不发送状态,WaitOne等待信号的发送。

可以通过构造函数的参数值来决定其初始状态,若为true则非阻塞状态,为false为阻塞状态。

如果某个线程调用WaitOne方法,则当信号处于发送状态时,该线程会得到信号, 继续向下执行。


其区别就在调用后,AutoResetEvent.WaitOne()每次只允许一个线程进入,当某个线程得到信号后,AutoResetEvent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只有继续等待.也就是说,AutoResetEvent一次只唤醒一个线程;

而ManualResetEvent则可以唤醒多个线程,因为当某个线程调用了ManualResetEvent.Set()方法后,其他调用WaitOne的线程获得信号得以继续执行,而ManualResetEvent不会自动将信号置为不发送。

也就是说,除非手工调用了ManualResetEvent.Reset()方法,则ManualResetEvent将一直保持有信号状态,ManualResetEvent也就可以同时唤醒多个线程继续执行。

举例:(msdn上的例子)

  1. using System;
  2. using System.Threading;
  3. class CalculateTest
  4. {
  5.     static void Main()
  6.     {
  7.         Calculate calc = new Calculate();
  8.         Console.WriteLine("Result = {0}."
  9.             calc.Result(234).ToString());
  10.         Console.WriteLine("Result = {0}."
  11.             calc.Result(55).ToString());
  12.     }
  13. }
  14. class Calculate
  15. {
  16.     double baseNumber, firstTerm, secondTerm, thirdTerm;
  17.     AutoResetEvent[] autoEvents;
  18.     ManualResetEvent manualEvent;
  19.     // Generate random numbers to simulate the actual calculations.
  20.     Random randomGenerator;
  21.     public Calculate()
  22.     {
  23.         autoEvents = new AutoResetEvent[]
  24.         {
  25.             new AutoResetEvent(false),
  26.             new AutoResetEvent(false),
  27.             new AutoResetEvent(false)
  28.         };
  29.         manualEvent = new ManualResetEvent(false);
  30.     }
  31.     void CalculateBase(object stateInfo)
  32.     {
  33.         baseNumber = randomGenerator.NextDouble();
  34.         // Signal that baseNumber is ready.
  35.         manualEvent.Set();
  36.     }
  37.     // The following CalculateX methods all perform the same
  38.     // series of steps as commented in CalculateFirstTerm.
  39.     void CalculateFirstTerm(object stateInfo)
  40.     {
  41.         // Perform a precalculation.
  42.         double preCalc = randomGenerator.NextDouble();
  43.         // Wait for baseNumber to be calculated.
  44.         manualEvent.WaitOne();
  45.         // Calculate the first term from preCalc and baseNumber.
  46.         firstTerm = preCalc * baseNumber * 
  47.             randomGenerator.NextDouble();
  48.         // Signal that the calculation is finished.
  49.         autoEvents[0].Set();
  50.     }
  51.     void CalculateSecondTerm(object stateInfo)
  52.     {
  53.         double preCalc = randomGenerator.NextDouble();
  54.         manualEvent.WaitOne();
  55.         secondTerm = preCalc * baseNumber * 
  56.             randomGenerator.NextDouble();
  57.         autoEvents[1].Set();
  58.     }
  59.     void CalculateThirdTerm(object stateInfo)
  60.     {
  61.         double preCalc = randomGenerator.NextDouble();
  62.         manualEvent.WaitOne();
  63.         thirdTerm = preCalc * baseNumber * 
  64.             randomGenerator.NextDouble();
  65.         autoEvents[2].Set();
  66.     }
  67.     public double Result(int seed)
  68.     {
  69.         randomGenerator = new Random(seed);
  70.         // Simultaneously calculate the terms.
  71.         ThreadPool.QueueUserWorkItem(
  72.             new WaitCallback(CalculateBase));
  73.         ThreadPool.QueueUserWorkItem(
  74.             new WaitCallback(CalculateFirstTerm));
  75.         ThreadPool.QueueUserWorkItem(
  76.             new WaitCallback(CalculateSecondTerm));
  77.         ThreadPool.QueueUserWorkItem(
  78.             new WaitCallback(CalculateThirdTerm));
  79.         // Wait for all of the terms to be calculated.
  80.         WaitHandle.WaitAll(autoEvents);
  81.         // Reset the wait handle for the next calculation.
  82.         manualEvent.Reset();
  83.         return firstTerm + secondTerm + thirdTerm;
  84.     }
  85. }

注释:

1.ManualResetEvent

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值