欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#中多線程ManualResetEvent 與 AutoResetEvent 區(qū)別

 更新時間:2020年07月16日 15:15:57   作者:千潯  
這篇文章主要介紹了C#中ManualResetEvent 與 AutoResetEvent 區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在多線程開發(fā)中,時常用到ManualResetEvent 與AutoResetEvent 。 它們?nèi)缤缆方煌ㄖ械男盘枱?。兩者之間有什么區(qū)別呢?

共同點:

均繼承EventWaitHandle 接口,因此,均具有以下功能:
Reset() //紅燈
Set() //綠燈
WaitOne() // 等待信號

不同點:

AutoResetEvent 收到 Set 后 , 一次只能執(zhí)行一個線程,其它線程繼續(xù) WaitOne 。
ManualResetEvent 收到 Set 后,所有處理 WaitOne 狀態(tài)線程均繼續(xù)執(zhí)行。

msdn 提到(如果沒有線程 處于WaitOne() 狀態(tài),而調(diào)用 Set ,AutoResetEvent將保持Set 狀態(tài)):

調(diào)用Set信號AutoResetEvent釋放等待線程。 AutoResetEvent 將保持終止?fàn)顟B(tài)直到一個等待線程釋放,并自動返回到非信號狀態(tài)。 如果沒有線程處于等待狀態(tài),狀態(tài)將無限期地保持已發(fā)出信號。

因此通常WatiOne 之前,先 Reset() 一下,清除Set 信號

需要注意的是(兩個 Set 調(diào)用之間時間較短,第二個 Set 信號可能會丟失,因此連續(xù) Set 調(diào)用,中間需要 Sleep 一定時間):

不能保證的每個調(diào)用Set方法將釋放一個線程。 如果兩次調(diào)用太靠近在一起,以便第二次調(diào)用前釋放線程發(fā)生,只有一個線程被釋放。 就像第二次調(diào)用未發(fā)生。 此外,如果Set時沒有等待的線程調(diào)用和AutoResetEvent已終止,則調(diào)用不起作用。

有網(wǎng)友說:

AutoResetEvent.Set() = ManualResetEvent.Set() + ManualResetEvent.Reset();

個人理解 ,這只是原理層面含義,實際使用過程中,有差別的,如下示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testManualResetEvent
{
  class Program
  {
    static object objManualResetEvent = new object();
    static System.Threading.ManualResetEvent manu = new System.Threading.ManualResetEvent(false);
     //static System.Threading.AutoResetEvent manu = new System.Threading.AutoResetEvent(false);
    static void Main(string[] args)
    {
      
      for (int i = 0; i < 10; i++)
      {
        System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { Product(); }));
        t.Start();
      }
      
      manu.Set();
      manu.Reset();

      Console.ReadKey();
    }

    static void Product()
    {
      manu.WaitOne(10000);
      Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
    }
  }
}

實際執(zhí)行結(jié)果 , 在 執(zhí)行 set 后 reset 前 ,有多少個線程喚起執(zhí)行,無法預(yù)料:

需要加鎖 ,確保一次通過一個線程:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testManualResetEvent
{
  class Program
  {
    static object objManualResetEvent = new object();
    static System.Threading.ManualResetEvent manu = new System.Threading.ManualResetEvent(false);
     //static System.Threading.AutoResetEvent manu = new System.Threading.AutoResetEvent(false);
    static void Main(string[] args)
    {
      
      for (int i = 0; i < 10; i++)
      {
        System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { Product(); }));
        t.Start();
      }
      
      manu.Set();

      //System.Threading.Thread.Sleep(100); //連續(xù) set 需要 sleep
      //manu.Set();
      //manu.Reset();

      //System.Threading.Thread.Sleep(100);
      //manu.Set();
      //manu.Reset();

      Console.ReadKey();
    }

    static void Product()
    {
      lock (objManualResetEvent)
      {
        manu.WaitOne(10000);          manu.Reset();
        Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
      }
    }
  }
}

執(zhí)行結(jié)果:

到此這篇關(guān)于C#中ManualResetEvent 與 AutoResetEvent 區(qū)別的文章就介紹到這了,更多相關(guān)C#中ManualResetEvent  AutoResetEvent 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論