详细解析C#多线程同步事件及等待句柄

2019-12-30 14:28:53王振洲

是不是更有感觉了?之后咱来看看另外几个东东:

System.Threading.WaitHandle.WaitOne 使线程一直等待,直到单个事件变为终止状态;

System.Threading.WaitHandle.WaitAny 阻止线程,直到一个或多个指示的事件变为终止状态;

System.Threading.WaitHandle.WaitAll 阻止线程,直到所有指示的事件都变为终止状态。

然后再来个例子,以WaitAll使用为例:


using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Threading; 
 
namespace AutoResetEventTest 
{ 
  class other 
  { 
    static void Main(string[] args) 
    { 
      Random randomGenerator = new Random(); 
      AutoResetEvent[] resets=new AutoResetEvent[5]; 
 
      for (int i = 0; i < 5; i++) 
      { 
        resets[i] = new AutoResetEvent(false); 
        int wTime = randomGenerator.Next(10)+1; 
 
        worker w = new worker(wTime, resets[i]); 
 
        Thread thrd1 = new Thread(new ThreadStart(w.work)); 
        thrd1.Start();  
      } 
      WaitHandle.WaitAll(resets); 
      Console.WriteLine("ALL worker done - main exiting."); 
    } 
 
  } 
 
  public class worker 
  { 
    public string name; 
    public int wTime; 
    public AutoResetEvent mEvent; 
 
    public worker(int w, AutoResetEvent m) 
    { 
      name = w.ToString(); 
      wTime = w * 1000; 
      mEvent = m; 
    } 
 
    public void work() 
    { 
      Console.WriteLine(name + " worker thread waiting for " + wTime + "...."); 
      Thread.Sleep(wTime); 
      Console.WriteLine(name + " worker thread back..."); 
      mEvent.Set(); 
    } 
  } 
} 

简单来说就是,开了5个线程,每个线程随机休眠若干秒,都完成后通知主线程退出,这里就开了一个AutoResetEvent数组,主线程就WaitHandle.WaitAll(resets) ,子线程休眠完后就Set1个AutoResetEvent,最后都Set完后,主线程就会往下执行。最后最后再来个买书付款取货的例子,加深理解:


using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Threading; 
 
namespace AutoResetEventTest 
{ 
  class Program 
  { 
    const int numIterations = 10; 
    static AutoResetEvent myResetEvent = new AutoResetEvent(false); 
    static AutoResetEvent ChangeEvent = new AutoResetEvent(false); 
    //static ManualResetEvent myResetEvent = new ManualResetEvent(false); 
    //static ManualResetEvent ChangeEvent = new ManualResetEvent(false); 
    static int number; //这是关键资源 
 
    static void Main() 
    { 
      Thread payMoneyThread = new Thread(new ThreadStart(PayMoneyProc)); 
      payMoneyThread.Name = "付钱线程"; 
      Thread getBookThread = new Thread(new ThreadStart(GetBookProc)); 
      getBookThread.Name = "取书线程"; 
      payMoneyThread.Start(); 
      getBookThread.Start(); 
 
      for (int i = 1; i <= numIterations; i++) 
      { 
        Console.WriteLine("买书线程:数量{0}", i); 
        number = i; 
        //Signal that a value has been written. 
        myResetEvent.Set(); 
        //ChangeEvent.Set(); 
        Thread.Sleep(10); 
      } 
      payMoneyThread.Abort(); 
      getBookThread.Abort(); 
    } 
 
    static void PayMoneyProc() 
    { 
      while (true) 
      { 
        myResetEvent.WaitOne(); 
        //myResetEvent.Reset(); 
        Console.WriteLine("{0}:数量{1}", Thread.CurrentThread.Name, number); 
        ChangeEvent.Set(); 
      } 
    } 
    static void GetBookProc() 
    { 
      while (true) 
      { 
        ChangeEvent.WaitOne(); 
        //ChangeEvent.Reset();         
        Console.WriteLine("{0}:数量{1}", Thread.CurrentThread.Name, number); 
        Console.WriteLine("------------------------------------------"); 
        //Thread.Sleep(0); 
      } 
    } 
  } 
}