C#2010: 執行緒的暫停和重啟(Auto/Manual ResetEvent)-以計時器為例

 

C#2010版以前, 執行緒可以使用Suspend( ) Resume( ) 等方法來暫停執行緒和重啟被暫停中的執行緒, 來到C#2010 Suspend( ) Resume( ) 被認為是過時的語法, 即便不使用Suspend( ) Resume( ), 仍然有其它方法可以達到執行緒的暫停和重啟, 也是本篇要討論的.

 

 

要讓程式暫停在某行程式碼, 直到再次下達指令才繼續執行, 我們必須借助

AutoResetEvent ManualResetEvent,  AutoResetEvent MannualResetEvent 的主要差異有二:

 

一、

AutoResetEvent MannualResetEvent 有一個叫WaitOne 的方法, 可以將緒行緒hand, 使用 Set 方法可讓被handWaitOne的執行緒繼續往下執行.

在宣告 AutoResetEvent MannualResetEvent 同時必須給定一個 bool 起始參數值, :        

                        AutoResetEvent TestTdEvent = new AutoResetEvent(false);

              ManualResetEvent MTestTdEvent = new ManualResetEvent(false);

 

false 表示程式遇到 WaitOne 方法時會被 hand . 反之則否.

 

AutoResetEvent 的起始值設 true, 一旦經過 WaitOne 之後就會被自動改成 false, 當第二次來到 WaitOne 的時就會被 hand , MannualResetEvent 一旦被設為 true 就會一直保持 true 的狀態, 必須使用 Reset 方法, 才能將起始值改成 false.

 

二、

若有多個執行緒被 hand WaitOne , AutoResetEvent 使用 Set 方法只能啟動某一個執行緒, 若有 n 個執行緒被 hand WaitOne , AutoResetEvent就要 Set n 次才可以讓所有執行緒繼續執行. MannualResetEvent 可以同時重啟所有被 hand WaitOne的執行緒.

 

 

 

AutoResetEvent:

===================================================================================

// 先行宣告必要的變數

Thread TestTd;                       // 宣告執行緒

bool FlagStop = false;   // 做為計時器的開關

AutoResetEvent TestTdEvent = new AutoResetEvent(false);

int Cumtm=0;

 

// 啟動執行緒

private void StartTestTd()

{

TestTd = new Thread(TestProc);

     TestTd.Start();

}

// 執行緒主要是每秒顯示一次系統的時間, FlagStop 被設為true時則進入 WaitOne

private void TestProc()

{

while (true)

     {

                if (FlagStop == true)

          {

                      TestTdEvent.WaitOne();

}

          else

          {

               Thread.Sleep(1000);

               Cumtm += 1;

               Console.WriteLine(DateTime.Now.ToString("HH:mm:ss"+ ", Cumtm = " + Cumtm);

}

}

}

// 記時器開關.

private void btmOnOff_Click(object sender, EventArgs e)

{

FlagStop = !FlagStop;

     if (FlagStop == false) TestTdEvent.Set(); 

}

 ===================================================================================

 


MannualResetEvent:

===================================================================================

// 先行宣告必要的變數

Thread MTestTd;                   // 宣告執行緒

bool FlagStop = false;   // 做為計時器的開關

ManualResetEvent MTestTdEvent = new ManualResetEvent(true);

int Cumtm=0;

 

// 啟動執行緒

private void StartTestTd()

{

MTestTd = new Thread(MTestProc);

     MTestTd.Start();

}

// 執行緒主要是每秒顯示一次系統的時間, 這裡因 MannualResetEvent bool起始值不會自動被設為false, 因此在這裡不用像AutoResetEvent判斷計時器是否要終止. bool起始值本身就可以拿來當執行緒的開關.

private void MTestProc()

{

while (true)

     {

MTestTdEvent.WaitOne();

Thread.Sleep(1000);

         Cumtm += 1;

         Console.WriteLine(DateTime.Now.ToString("HH:mm:ss"+ ", Cumtm = " + Cumtm);

     }

}

// 記時器開關.

private void btmOnOff_Click(object sender, EventArgs e)

{

FlagStop = !FlagStop;

     if (FlagStop == true)

{        

MTestTdEvent.Reset(); 

}

     else

     {

MTestTdEvent.Set(); 

}

}

===================================================================================

這裡只有做計時器的範例, 至於要檢驗多個執行緒暫停重啟的部份, 只要再多加一個計時器便可明白, 這裡就不多做說明囉~ :)

arrow
arrow
    全站熱搜

    Keep Practicing 發表在 痞客邦 留言(0) 人氣()