1. 程式人生 > >AutoResetEvent 與 ManualResetEvent 控制執行緒暫停及恢復運作 « 關於網路那些事...

AutoResetEvent 與 ManualResetEvent 控制執行緒暫停及恢復運作 « 關於網路那些事...

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

如果你喜歡我們的文章內容,請在這裡按個讚