一、基礎概念
在多任務環境下,線程等待是非常重要的一個概念。線程等待可以讓一個線程等待另外一個線程完成某些操作,然後再繼續執行。在C#中,線程等待是通過System.Threading命名空間中的WaitHandle類和其派生類來實現的。
WaitHandle類提供WaitOne()和WaitAny()方法,它們都可以讓一個線程等待某個事件,直到該事件發生或超時。WaitOne()方法會等待一個WaitHandle對象的信號,並且支持超時;WaitAny()方法會等待多個WaitHandle對象中的任意一個被信號激活,並且支持超時。
在具體的應用場景中,我們可以使用ManualResetEvent、AutoResetEvent、CountdownEvent和SemaphoreSlim等類來創建WaitHandle對象。
二、ManualResetEvent和AutoResetEvent
ManualResetEvent和AutoResetEvent都是WaitHandle的派生類,它們可以用於線程等待。在 ManualResetEvent 中,線程會一直等待直到該事件被信號激活。而在 AutoResetEvent 中,線程會等待事件被信號激活一次,然後自動重置,以便於下次被信號激活。
下面是使用ManualResetEvent實現線程等待的代碼示例:
ManualResetEvent event1 = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem(state => { Console.WriteLine("Thread 1 is running"); Thread.Sleep(1000); Console.WriteLine("Thread 1 set the event"); event1.Set(); }); Console.WriteLine("Main thread is waiting for event"); event1.WaitOne(); Console.WriteLine("Main thread received event");
上述示例使用ManualResetEvent實現了一個線程等待的功能。在主線程中,首先創建了一個ManualResetEvent對象,並且初始化為未激活狀態。然後開啟一個新的線程,在該線程中等待1秒鐘,並且在1秒鐘後激活ManualResetEvent對象。在主線程中調用event1.WaitOne()方法等待事件的激活,直到該事件被激活後,主線程才會繼續執行。
三、CountdownEvent和SemaphoreSlim
CountdownEvent和SemaphoreSlim也是WaitHandle的派生類。CountdownEvent可以用來等待一組操作完成,而SemaphoreSlim可以用來控制同時執行的線程數量。
下面是使用CountdownEvent實現線程等待的代碼示例:
CountdownEvent countdown = new CountdownEvent(3); for (int i = 1; i { Console.WriteLine($"Thread {i} is running"); Thread.Sleep(1000); Console.WriteLine($"Thread {i} is done"); countdown.Signal(); }); } countdown.Wait(); Console.WriteLine("All threads are done");
上述示例使用CountdownEvent實現了同時等待多個線程完成的功能。首先創建了一個CountdownEvent對象,並且把初始計數器設置為3。然後開啟三個新的線程,在每個線程中等待1秒鐘,並且在1秒鐘後為CountdownEvent對象計數。在主線程中調用countdown.Wait()方法等待所有的線程完成,並且在所有線程完成後繼續執行。
下面是使用SemaphoreSlim實現控制線程數量的代碼示例:
SemaphoreSlim semaphore = new SemaphoreSlim(3); for (int i = 1; i { await semaphore.WaitAsync(); Console.WriteLine($"Thread {i} start"); Thread.Sleep(1000); Console.WriteLine($"Thread {i} end"); semaphore.Release(); }); }
上述示例使用SemaphoreSlim實現了在同一時間內只允許3個線程同時執行的功能。首先創建了一個SemaphoreSlim對象,並且初始計數器設置為3。然後使用ThreadPool開啟5個新的線程,在每個線程中等待SemaphoreSlim對象信號,當計數器大於0時,線程可以執行,並且計數器會減1。在線程執行完畢後,計數器會加1,以便於其他線程可以繼續執行。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/230197.html