AutoResetEvent 與 ManualResetEvent 控制執行緒暫停及恢復運作 « 關於網路那些事...
阿新 • • 發佈:2018-12-23
C# - AutoResetEvent 與 ManualResetEvent 控制執行緒暫停及恢復運作
C# 有兩個類別可以用來調控執行緒
- AutoResetEvent
- ManualResetEvent
WaitOne 暫停執行緒
AutoResetEvent.WaitOne 方法可以讓執行緒進入 Join (WaitSleepJoin) 暫停狀態
Set 繼續執行緒動作
AutoResetEvent.Set 方法可以讓暫停狀態的執行緒恢復運作
ManualResetEvent 則需要呼叫 .Set 與 .Reset
這裡舉例,在 A B 兩個任務類別中
在 任務A 執行了 WaitOne() 先讓 任務A 進入 WaitSleepJoin Block 狀態
當 任務B 執行到偶數時,就執行 Set() 將 A任務 恢復運作
class Program { private Thread MissionA_Thread; private Thread MissionB_Thread; private static AutoResetEvent _AutoResetEvent = new AutoResetEvent(false); static void Main(string[] args) { Program mProgram = new Program(); mProgram.ProvideMission(); Console.ReadKey(); } private void ProvideMission() { //指定委派A物件 ThreadStart MissionA_Tg = new ThreadStart(MissionA); //建立A任務執行緒 MissionA_Thread = new Thread(MissionA_Tg); //指定委派B物件 ThreadStart MissionB_Tg = new ThreadStart(MissionB); //建立B任務執行緒 MissionB_Thread = new Thread(MissionB_Tg); //啟動執行緒 MissionA_Thread.Start(); MissionB_Thread.Start(); } //任務A private void MissionA() { for (int i = 0; i < 10; i++) { _AutoResetEvent.WaitOne(); Console.WriteLine("A" + i); Thread.Sleep(1000); } } //任務B private void MissionB() { for (int i = 0; i < 10; i++) { if (i % 2 == 0) { _AutoResetEvent.Set(); } Console.WriteLine("B" + i); Thread.Sleep(2000); } } }
若是 ManualResetEvent 則需要再多加一次 Reset()
class Program { private Thread MissionA_Thread; private Thread MissionB_Thread; private static ManualResetEvent _ManualResetEvent = new ManualResetEvent(false); static void Main(string[] args) { Program mProgram = new Program(); mProgram.ProvideMission(); Console.ReadKey(); } private void ProvideMission() { //指定委派A物件 ThreadStart MissionA_Tg = new ThreadStart(MissionA); //建立A任務執行緒 MissionA_Thread = new Thread(MissionA_Tg); //指定委派B物件 ThreadStart MissionB_Tg = new ThreadStart(MissionB); //建立B任務執行緒 MissionB_Thread = new Thread(MissionB_Tg); //啟動執行緒 MissionA_Thread.Start(); MissionB_Thread.Start(); } //任務A private void MissionA() { for (int i = 0; i < 10; i++) { _ManualResetEvent.WaitOne(); Console.WriteLine("A" + i); Thread.Sleep(1000); } } //任務B private void MissionB() { for (int i = 0; i < 10; i++) { if (i % 2 == 0) { _ManualResetEvent.Set(); _ManualResetEvent.Reset(); } Console.WriteLine("B" + i); Thread.Sleep(2000); } } }
判斷 WaitOne
在實際應用時,會先判斷 WaitOne 的狀態,確定有進入暫停狀態,才進行 Set
if (_AutoResetEvent.WaitOne(0) == false){} _AutoResetEvent.Set(); }
範例
class Program { private Thread MissionA_Thread; private Thread MissionB_Thread; private static AutoResetEvent _AutoResetEvent = new AutoResetEvent(false); static void Main(string[] args) { Program mProgram = new Program(); mProgram.ProvideMission(); Console.ReadKey(); } private void ProvideMission() { //指定委派A物件 ThreadStart MissionA_Tg = new ThreadStart(MissionA); //建立A任務執行緒 MissionA_Thread = new Thread(MissionA_Tg); //指定委派B物件 ThreadStart MissionB_Tg = new ThreadStart(MissionB); //建立B任務執行緒 MissionB_Thread = new Thread(MissionB_Tg); //啟動執行緒 MissionA_Thread.Start(); MissionB_Thread.Start(); } //任務A private void MissionA() { for (int i = 0; i < 10; i++) { _AutoResetEvent.WaitOne(); Console.WriteLine("A" + i); } } //任務B private void MissionB() { for (int i = 0; i < 10; i++) { if (i % 2 == 0) { if(_AutoResetEvent.WaitOne(0)== false) { _AutoResetEvent.Set(); } } Console.WriteLine("B" + i); Thread.Sleep(2000); } } }
如果你喜歡我們的文章內容,請在這裡按個讚
Tweet