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);
}
}
}