灵活使用多线程编程——AutoResetEvent类(转)

AutoResetEvent类

     该类的作用是通知正在等待的线程已发生的事件。该类存在于mscorlib.DLL中。

     在.Net Framework 2.0中,该类是继承自EventWaitHalder,AutoResetEvent在功效上等同于 EventResetModel.AutoReset创建的EventWaitHandle。下面我们反编译该类的代码,下边为该类得构造函数的代码:


 1 [ComVisible(true), HostProtection(SecurityAction.LinkDemand, Synchronization=true, ExternalThreading=true)]
 2 public sealed class AutoResetEvent : EventWaitHandle
 3 {
 4     // Methods
 5     [SecuritySafeCritical]
 6     public AutoResetEvent(bool initialState) : base(initialState, EventResetMode.AutoReset)
 7     {
 8     }
 9 }
10 
11 

AutoResetEvent是允许线程通过发信号进行互相通信访问的。通常,此类通信涉及线程需要独占访问资源。

线程通过调用AutoResetEvent上的WaitOne来等待信号,如果AutoResetEvent处于非终止状态的话,则该线程阻塞,并且等待当前控制资源的线程通过调用Set发出资源可用信号。

调用Set向AutoResetEvent发出信号以释放等待的线程,AutoResetEvent将处于终止状态,直到一个等待的线程释放,然后自动返回非终止状态,如果没有任何线程在等待,则该信号无限期的保持在终止状态。

可以通过将一个Bool值传给AutoResetEvent的构造函数,用于设置是否为非终止状态。如果传入的为TRUE,则初始状态为终止状态,否则为FALSE。

下面我们通过一个示例来详细说明该类的用法:


  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using System.Threading;
 10 
 11 namespace WindowsFormsApplication2
 12 {
 13     public partial class Form2 : Form
 14     {
 15         /// <summary>
 16         /// 第一次计算的结果
 17         /// </summary>
 18         double firstNumber = 0;
 19         /// <summary>
 20         /// 第二次计算的结果
 21         /// </summary>
 22         double secondNumber = 0;
 23         /// <summary>
 24         /// 第三次计算的结果
 25         /// </summary>
 26         double thirdNumber = 0;
 27 
 28         /// <summary>
 29         /// 三次计算对应的线程等待变量
 30         /// </summary>
 31         AutoResetEvent[] autoResetEvent = null;
 32 
 33         /// <summary>
 34         /// 随机变量种子
 35         /// </summary>
 36         Random random = null;
 37 
 38         public Form2()
 39         {
 40             InitializeComponent();
 41 
 42             //初始设置为非终止状态,此时三个变量均处于阻塞状态
 43             autoResetEvent = new AutoResetEvent[]{
 44                 new AutoResetEvent(false),
 45                 new AutoResetEvent(false),
 46                 new AutoResetEvent(false)
 47             };
 48         }
 49 
 50         private void button1_Click(object sender, EventArgs e)
 51         {
 52             MessageBox.Show(SimuValue(Int32.Parse(this.textBox1.Text)).ToString());
 53         }
 54 
 55         /// <summary>
 56         /// 计算第一个数值
 57         /// </summary>
 58         /// <param name="stateInfo"></param>
 59         void SimuFirstNumber(object stateInfo)
 60         {
 61             double v = random.NextDouble();
 62             double p = random.NextDouble();
 63 
 64             firstNumber = v * p;
 65 
 66             //发出变量将该事件状态设置为终止状态,允许一个或多个等待线程继续
 67             autoResetEvent[0].Set();
 68         }
 69         /// <summary>
 70         /// 计算第二个数值
 71         /// </summary>
 72         /// <param name="stateInfo"></param>
 73         void SimuSecondNumber(object stateInfo)
 74         {
 75             double v = random.NextDouble();
 76             double p = random.NextDouble();
 77 
 78             secondNumber = v * p;
 79 
 80             autoResetEvent[1].Set();
 81         }
 82         /// <summary>
 83         /// 计算第三个数值
 84         /// </summary>
 85         /// <param name="stateInfo"></param>
 86         void SimuThirdNumber(object stateInfo)
 87         {
 88             double v = random.NextDouble();
 89             double p = random.NextDouble();
 90 
 91             thirdNumber = v * p;
 92 
 93             autoResetEvent[2].Set();
 94         }
 95 
 96         /// <summary>
 97         /// 计算所有的数值乘积
 98         /// </summary>
 99         /// <param name="v"></param>
100         double SimuValue(int v)
101         {
102             random = new Random(v);
103 
104             //调用多线程计算三个数值
105             ThreadPool.QueueUserWorkItem(new WaitCallback(SimuFirstNumber));
106             ThreadPool.QueueUserWorkItem(new WaitCallback(SimuSecondNumber));
107             ThreadPool.QueueUserWorkItem(new WaitCallback(SimuThirdNumber));
108 
109             //等到三个线程计算完毕
110             WaitHandle.WaitAll(autoResetEvent);
111 
112             return firstNumber * secondNumber * thirdNumber;
113         }
114     }
115 }
116 

AutoResetEvent中比较有用的函数分别为以下几个:

     1.Set()  将事件的状态位置设置为终止状态,允许一个或多个等待线程继续。

     2.ReSet()将事件的状态设置为非终止状态,阻塞该线程。

     3.WaitOne()阻止当前线程。直到当前WaitHandle收到信号。

posted @ 2011-02-25 15:38  董雨  阅读(313)  评论(0编辑  收藏  举报