C# ManualResetEvent使用測試

一直對ManualResetEvent的用法不是很明白,今天決定寫些小程序,測試一下,直觀感受它的用法。

MSDN的解釋: 通知一個或多個正在等待的線程已發生事件。 此類不能被繼承。

Part1:初始化

        // 初始化一個ManualResetEvent實例
        private static ManualResetEvent _mer = new ManualResetEvent(false);
可見,初始化時接受一個bool值,它是有什麼作用呢?

MSND的解釋:用一個指示是否將初始狀態設置爲終止的布爾值初始化 ManualResetEvent類的新實例。即:可以通過將布爾值傳遞給構造函數來控制 ManualResetEvent 的初始狀態,如果初始狀態處於終止狀態,爲 true;否則爲 false

用程序來直觀感受一下:

static void Main(string[] args)
        {
            Console.WriteLine("Enter Main" + Thread.CurrentThread.Name);

            for (int id = 0; id < 2; id++)
            {
                Thread th = new Thread(new ThreadStart(ThreadProc));
                th.Name = "thread_" + id.ToString();
                th.Start();
            }
        }
private static void ThreadProc()
        {
            Console.WriteLine("Enter ThreadProc" + Thread.CurrentThread.Name);
            Console.WriteLine("before WaitOne " + Thread.CurrentThread.Name);
            _mer.WaitOne();
            Console.WriteLine("after WaitOne " + Thread.CurrentThread.Name);
            Console.WriteLine("Exit ThreadProc" + Thread.CurrentThread.Name);
        }

測試結果:



先加個解釋,ThreadProc裏用到了WaitOne(), MSDN的解釋是:阻止當前線程,直到當前 WaitHandle 收到信號。 (繼承自WaitHandle。)

回到初始化,初始化爲false,即_mer是非終止狀態,這裏我想加個自己的理解,非終止狀態就是工作狀態,就是說_mer是起作用的,從程序的結果可以看到,

程序停在了_mer.WaitOne(); 這一句,沒有輸出Console.WriteLine("after WaitOne " + Thread.CurrentThread.Name);這句,就是說_mer起作用了。

如果初始化時是true,即終止狀態,就是非工作狀態,程序執行的結果就是執行完畢,閃退。

總結: 初始化爲true,終止狀態,即不起作用狀態;初始化爲false,非終止狀態,即起作用狀態。


Part2:Set與Reset

ManualResetEvent.Set()   MSDN的解釋:將事件狀態設置爲終止狀態,允許一個或多個等待線程繼續。 (繼承自EventWaitHandle。)

也就是將ManualResetEvent實例設置爲不起作用狀態。

程序測試:

_mer初始化還是false,Main() 方法里加了一句: _mer.Set();

        static void Main(string[] args)
        {
            Console.WriteLine("Enter Main" + Thread.CurrentThread.Name);
            _mer.Set();

            for (int id = 0; id < 2; id++)
            {
                Thread th = new Thread(new ThreadStart(ThreadProc));
                th.Name = "thread_" + id.ToString();
                th.Start();
            }
        }
執行結果:執行完畢,閃退。即: _mer.WaitOne(); 不起作用。


ManualResetEvent.Reset()  MSDN解釋:將事件狀態設置爲非終止狀態,導致線程阻止。

即設置爲起作用狀態。

程序測試:

初始化一個爲true的實例,Main()方法里加了一句:_mer.Reset();

static void Main(string[] args)
        {
            Console.WriteLine("Enter Main" + Thread.CurrentThread.Name);
            _mer.Reset();

            for (int id = 0; id < 2; id++)
            {
                Thread th = new Thread(new ThreadStart(ThreadProc));
                th.Name = "thread_" + id.ToString();
                th.Start();
            }
        }

執行結果:


可見, 初始化爲true,終止狀態(不起作用狀態),Reset()後,就爲非終止狀態(起作用狀態)。


Part3 : WaitOne(Int32)

 MSDN的解釋:阻止當前線程,直到當前 WaitHandle 收到信號,同時使用 32 位帶符號整數指定時間間隔(以毫秒爲單位)
   

     private static void ThreadProc()
        {
            Console.WriteLine("Enter ThreadProc" + Thread.CurrentThread.Name);
            Console.WriteLine("before WaitOne " + Thread.CurrentThread.Name);
            _mer.WaitOne(5000);
            Console.WriteLine("after WaitOne " + Thread.CurrentThread.Name);
            Console.WriteLine("Exit ThreadProc" + Thread.CurrentThread.Name);


            Console.Read();
        }
程序中有一句:
 _mer.WaitOne(5000);
阻塞5秒鐘,程序執行完畢。
如果在Main方法里加上這兩句:
            Thread.Sleep(2000);
            _mer.Set();

<pre name="code" class="csharp">static void Main(string[] args)
        {
            Console.WriteLine("Enter Main" + Thread.CurrentThread.Name);

            for (int id = 0; id < 2; id++)
            {
                Thread th = new Thread(new ThreadStart(ThreadProc));
                th.Name = "thread_" + id.ToString();
                th.Start();
            }

            Thread.Sleep(2000);
            _mer.Set();
        }
程序執行情況是: ThreadProc阻塞,2秒鐘接收到Set()信號, 執行WaitOne(5000)後面的語句,即只阻塞了兩秒。

今天是對ManualResetEvent的幾個方法有了直觀的瞭解, 接下來有時間再測試他們在線程同步中的使用。

發佈了49 篇原創文章 · 獲贊 11 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章