C#執行緒同步手動重置事件——ManualResetEvent

桃子夭夭發表於2015-08-20

和AutoResetEvent類的區別是,Manual一旦set後不會自動reset,會放行所有waitone的執行緒,而autoresetevent每一次set之後只會放行一個waitone的執行緒,然後立即自動reset。這就是自動和手動的區別,實際上說的是自動reset和手動reset。

這裡就貼一段翻譯註釋的msdn官方程式碼吧。

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

namespace myTest
{
    class Program
    {
        private static ManualResetEvent mre = new ManualResetEvent(false);
        static void Main(string[] args)
        {
            Console.WriteLine("\n開啟3個被ManualResetEvent阻塞的執行緒,並分別命名:\n");

            for (int i = 0; i <= 2; i++)
            {
                Thread t = new Thread(ThreadProc);
                t.Name = "Thread_" + i;
                t.Start();
            }

            Thread.Sleep(500);
            Console.WriteLine("\n當所有的執行緒都start後,按下Enter鍵以執行ManualResetEvent的set方法" +
                              "\n來釋放所有執行緒的阻塞狀態.\n");
            Console.ReadLine();

            mre.Set();

            Thread.Sleep(500);
            Console.WriteLine("\n一旦ManualResetEvent物件收到了set的訊號,後面再呼叫WaitOne()方法的執行緒" +
                              "\n就不會被阻塞了.按下Enter鍵檢視結果.\n");
            Console.ReadLine();

            for (int i = 3; i <= 4; i++)
            {
                Thread t = new Thread(ThreadProc);
                t.Name = "Thread_" + i;
                t.Start();
            }

            Thread.Sleep(500);
            Console.WriteLine("\n按下Enter鍵呼叫 Reset(), 這樣後邊再啟動的執行緒呼叫waitone()時又會被阻塞了" );
            Console.ReadLine();

            mre.Reset();

            // 啟動一個被ManualResetEvent阻塞的執行緒
            Thread t5 = new Thread(ThreadProc);
            t5.Name = "Thread_5";
            t5.Start();

            Thread.Sleep(500);
            Console.WriteLine("\n按下Enter鍵呼叫 Set() 並結束此次演示.");
            Console.ReadLine();

            mre.Set();
Console.ReadLine();
           
        }
        private static void ThreadProc()
        {
            string name = Thread.CurrentThread.Name;

            Console.WriteLine(name + " 啟動並呼叫 mre.WaitOne()");

            mre.WaitOne();

            Console.WriteLine(name + " 退出.");
        }
    }
}

 

相關文章