首頁  >  文章  >  後端開發  >  C#使用AutoResetEvent實現同步的詳解及實例

C#使用AutoResetEvent實現同步的詳解及實例

黄舟
黄舟原創
2017-03-28 11:10:421681瀏覽

這篇文章主要為大家詳細介紹了C#使用AutoResetEvent實現同步的相關資料,具有一定的參考價值,有興趣的小伙伴們可以參考一下

前幾天碰到一個執行緒的順序執行的問題,就是一個非同步執行緒往A介面發送一個資料請求。另外一個非同步執行緒往B介面發送一個資料請求,當A和B都執行成功了,再往C介面發送一個請求。說真的,一直做BS項目,對執行緒了解,還真不多。就知道AutoResetEvent這個東西跟執行緒有關,用來處理執行緒切換之類,於是決定用AutoResetEvent來處理上面的問題。

於是網路上找相關資料:

原來,AutoResetEvent在.Net多執行緒程式設計中常用到。當某個執行緒呼叫WaitOne方法後,訊號處於發送狀態,該執行緒會得到訊號, 程式就會繼續向下執行,否則就等待。而且AutoResetEvent.WaitOne()每次只允許一個執行緒進入,當某個執行緒得到訊號後,AutoResetEvent會自動又將訊號置為不傳送狀態,其他呼叫WaitOne的執行緒只有繼續等待.也就是說,AutoResetEvent一次只喚醒一個線程,其他線程還是堵塞。

簡介

AutoResetEvent(bool initialState):建構子,用一個指示是否將初始狀態設為終止的布林值初始化該類別的新實例。
    false:無訊號,子執行緒的WaitOne方法不會被自動呼叫
    true:有訊號,子執行緒的WaitOne方法會自動呼叫
# Reset ():將事件狀態設為非終止狀態,導致執行緒阻止;如果該操作成功,則傳回true;否則,傳回false。
 Set ():將事件狀態設為終止狀態,允許一個或多個等待執行緒繼續;如果該操作成功,則傳回true;否則,傳回false。
 WaitOne(): 阻止目前線程,直到收到訊號。
 WaitOne(TimeSpan, Boolean) :阻止目前線程,直到目前實例收到訊號,使用 TimeSpan 度量時間間隔並指定在等待之前是否退出同步域。   
    WaitAll():等待全部訊號。 

實作

 class Program
 {

  static void Main()
  {
   Request req = new Request();

   //这个人去干三件大事 
   Thread GetCarThread = new Thread(new ThreadStart(req.InterfaceA));
   GetCarThread.Start();

   Thread GetHouseThead = new Thread(new ThreadStart(req.InterfaceB));
   GetHouseThead.Start();

   //等待三件事都干成的喜讯通知信息 
   AutoResetEvent.WaitAll(req.autoEvents);

   //这个人就开心了。 
   req.InterfaceC();

   System.Console.ReadKey();
  }
 }

 public class Request
 {
  //建立事件数组 
  public AutoResetEvent[] autoEvents = null;

  public Request()
  {
   autoEvents = new AutoResetEvent[]
   {
    new AutoResetEvent(false),
    new AutoResetEvent(false)
   };
  }

  public void InterfaceA()
  {
   System.Console.WriteLine("请求A接口");

   Thread.Sleep(1000*2);

   autoEvents[0].Set();

   System.Console.WriteLine("A接口完成");
  }

  public void InterfaceB()
  {
   System.Console.WriteLine("请求B接口");

   Thread.Sleep(1000 * 1);

   autoEvents[1].Set();

   System.Console.WriteLine("B接口完成");
  }

  public void InterfaceC()
  {
   System.Console.WriteLine("两个接口都已经请求完,正在处理C");
  }
 }

注意,WaitOne 或是WaitAll 最好都加上逾時時間。否則沒有收到訊號,線程一直會阻塞。 

後話

這個只是上面的場景的一個簡化,主要是用來解決剛剛我說的那個場景的問題。
以上是自己對AutoResetEvent的使用總結。不足之處請各位指點一二。

以上是C#使用AutoResetEvent實現同步的詳解及實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn