詳解 ManualResetEvent

轉 http://www.cnblogs.com/li-peng/p/3291306.htmlhtml

今天詳細說一下ManualResetEvent函數

它能夠通知一個或多個正在等待的線程已發生事件,容許線程經過發信號互相通訊,來控制線程是否可心訪問資源ui

當一個線程開始一個活動(此活動必須完成後,其餘線程才能開始)時,它調用 Reset 以將 ManualResetEvent 置於非終止狀態。此線程可被視爲控制 ManualResetEvent。調用 ManualResetEvent上的 WaitOne 的線程將阻止,並等待信號。當控制線程完成活動時,它調用 Set 以發出等待線程能夠繼續進行的信號。並釋放全部等待線程。spa

一旦它被終止,ManualResetEvent 將保持終止狀態,直到它被手動重置。即對 WaitOne 的調用將當即返回。線程

上面是它的功能描述,你可能會有點暈。我會用代碼一點一點解釋它,看完我寫的這些內容,你本身運行一下代碼你就會明白它的功能3d

源代碼:ManualResetEventDemo.rarcode

咱們從初始化來開始講htm

能夠經過將布爾值傳遞給構造函數來控制 ManualResetEvent 的初始狀態,若是初始狀態處於終止狀態,爲 true;不然爲 false。blog

我用代碼 讓你們看一下什麼是終止狀態和非止狀態事件

先看一下代碼

class  Program
    {
        static  ManualResetEvent _mre = new  ManualResetEvent( false );
        static  void  Main( string [] args)
        {
            Thread[] _threads = new  Thread[3];
            for  ( int  i = 0; i < _threads.Count(); i++)
            {
                _threads[i] = new  Thread(ThreadRun);
                _threads[i].Start();
            }
           
        }
 
        static  void  ThreadRun()
        {
            int  _threadID = 0;
            while  ( true )
            {
                _mre.WaitOne();
                _threadID = Thread.CurrentThread.ManagedThreadId;
                Console.WriteLine( "current Tread is "  + _threadID);
                Thread.Sleep(TimeSpan.FromSeconds(2));
                  
            }
        }
    }

當初始化爲true時,爲終止狀態

static  ManualResetEvent _mre = new  ManualResetEvent( true );

執行結果

 

當初始化爲false時,爲非終止狀態

static  ManualResetEvent _mre = new  ManualResetEvent( false );

執行結果爲

這樣咱們就能看出來

終止狀態時WaitOne()容許線程訪問下邊的語句

非終止狀態時WaitOne()阻塞線程,不容許線程訪問下邊的語句

咱們也能夠把WaitOne()放在方法最下邊

static  void  ThreadRun()
         {
             int  _threadID = 0;
             while  ( true )
             {
                 
                 _threadID = Thread.CurrentThread.ManagedThreadId;
                 Console.WriteLine( "current Tread is "  + _threadID);
                 Thread.Sleep(TimeSpan.FromSeconds(2));
                 _mre.WaitOne();
             }
         }

當初始化爲true時執行結果和上邊的同樣會不停的執行

初始化爲false時執行到waitOne()時就阻塞線程不會再往下執行了

接下來你可能就會想當在非終止狀態時怎麼讓線程繼續執行,怎麼再讓它停下來,這就要用了set()和Reset()方法了

把非終止狀態改成終止狀態用Set()方法

把終止狀態改成非終止狀態用Reset()方法

我用用代碼來實現它們只要把咱們上 邊的代碼作一下改動

class  Program
     {
         static  ManualResetEvent _mre = new  ManualResetEvent( false );
         static  void  Main( string [] args)
         {
             Console.WriteLine( "輸入1爲Set()   開始運行" );
             Console.WriteLine( "輸入2爲Reset() 暫停運行" );
             Thread[] _threads = new  Thread[3];
             for  ( int  i = 0; i < _threads.Count(); i++)
             {
                 _threads[i] = new  Thread(ThreadRun);
                 _threads[i].Start();
             }
             while  ( true )
             {
                 switch  (Console.ReadLine())
                 {
                     case  "1" :
                         _mre.Set();
                         Console.WriteLine( "開始運行" );
                         break ;
                     case  "2" :
                         _mre.Reset();
                         Console.WriteLine( "暫停運行" );
                         break ;
                     default :
                         break ;
                 }
             }
            
         }
 
         static  void  ThreadRun()
         {
             int  _threadID = 0;
             while  ( true )
             {
                 
                 _threadID = Thread.CurrentThread.ManagedThreadId;
                 Console.WriteLine( "current Tread is "  + _threadID);
                 Thread.Sleep(TimeSpan.FromSeconds(2));
                 _mre.WaitOne();
             }
         }
     }

 

 

當輸入1 時會調用 Set()方法 ManualResetEvent 處於終止狀態會WaitOne不會阻塞線程會一直運行下去

當輸入2時會調用 Reser()方法ManualResetEvent處於非終止狀態WaitOne會阻塞線程直到再調用 Set()方法

看一下執行結果吧

 代碼:ManualResetEventDemo.rar

相關文章
相關標籤/搜索