本文主要是介绍控制threadpool執行緒的順序啟動 - WaitHandle.WaitAll 方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
[C#.NET][Thread] 執行緒的順序啟動 - WaitHandle.WaitAll 方法
WaitHandle.WaitAll 跟Thread.Join很像,都是執行緒等待,在功能上就是執行緒的順序啟動,如同我之前寫過的 [Thread] 執行緒的順序啟動 - Thread.Join方法,實作過程很簡單只需要注意以下兩點
1.WaitHandle是一個抽像類別所以我們得實體化它的子類別,也就是 ManualResetEvent 類別 或AutoResetEvent 類別,如下所示
static WaitHandle[] waitHandles = new WaitHandle[]
{ new AutoResetEvent(false), new AutoResetEvent(false)
};
2.再來,看一下多載清單,WaitHandle.WaitAll方法只收WaitHandle[]參數
接下來則演練如何實作WaitHandle,我用一個類別將我要的資訊擺進去
public class Calculator
{public string Name { get; set; }public long Result { get; set; }private AutoResetEvent _WaitHandle;public AutoResetEvent WaitHandle{get { return _WaitHandle; }set { _WaitHandle = value; }}
}
用戶端的呼叫
static WaitHandle[] waitHandles = null;
static object _lock = new object();static void Main(string[] args)
{DateTime dt = DateTime.Now;Console.WriteLine("進入主執行緒");//建立集合List<Calculator> calculator = new List<Calculator>() {new Calculator{Result=0,WaitHandle=new AutoResetEvent(false),Name="NO.1"},new Calculator{Result=0,WaitHandle=new AutoResetEvent(false),Name="NO.2"}};//建立WaitHandle陣列,因為WaitHandle.WaitAll只收陣列waitHandles = new WaitHandle[calculator.Count];for (int i = 0; i < calculator.Count; i++){waitHandles[i] = calculator[i].WaitHandle;}ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), calculator[0]);ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), calculator[1]);//等待這兩隻執行緒完成工作WaitHandle.WaitAll(waitHandles);Console.WriteLine("子執行緒完成,花費時間 ={0})", (DateTime.Now - dt).TotalMilliseconds);Console.ReadKey();
}
模擬大量運算工作
static void DoTask(Object state)
{lock (_lock){if (_isTimeOut)return;Calculator calculator = (Calculator)state;Console.WriteLine("{0} 進入子執行緒", calculator.Name);AutoResetEvent reset = calculator.WaitHandle;for (long i = 0; i < 1000000000; i++){calculator.Result++;}Console.WriteLine("{0} 計算結果 :{1}", calculator.Name, calculator.Result.ToString());Console.WriteLine("{0} 離開子執行緒", calculator.Name);reset.Set();}
}
執行結果就跟我想的一樣,因為 WaitHandle.WaitAll(waitHandles)的關係,主執行緒乖乖的等待所有執行緒完成工作,
WaitHandle.WaitAll還可以設定等待時間,我們把WaitHandle.WaitAll(waitHandles)改成WaitHandle.WaitAll(waitHandles,2000),表示主執行緒願意等子執行緒2秒。
因為ThreadPool沒有Abort方法所以,我加一個變數_isTimeOut旗標,用來判斷執行緒是否結束工作。
再改裝一下程式碼,
static bool _isTimeOut=false; static void Main(string[] args) { …略 //等待這兩隻執行緒完成工作 WaitHandle.WaitAll(waitHandles,2000); _isTimeOut = true; Console.WriteLine("子執行緒完成,花費時間 ={0})", (DateTime.Now - dt).TotalMilliseconds); Console.ReadKey(); }
static void DoTask(Object state) { lock (_lock) { if (_isTimeOut) return; …略 for (longi = 0; i < 1000000000; i++) { //離開子執行緒旗標 if (_isTimeOut) { Console.WriteLine("{0} 計算結果 :{1}", calculator.Name, calculator.Result.ToString()); Console.WriteLine("{0} 離開子執行緒", calculator.Name); return; } calculator.Result++; } …略 } }
執行結果,主執行緒等了2秒後,就不想等了,於是就叫子執行緒停下他的工作。
WaitHandle.WaitAny方法就是等待任何一隻執行緒完成工作
static void Main(string[] args)
{…略//等待任一隻執行緒完成工作int index = WaitHandle.WaitAny(waitHandles);_isTimeOut = true;Console.WriteLine("子執行緒完成,花費時間 ={0})", (DateTime.Now - dt).TotalMilliseconds);Console.ReadKey();
}
執行結果:可以觀察出當任一執行緒完成工作後則離開所有子執行緒
这篇关于控制threadpool執行緒的順序啟動 - WaitHandle.WaitAll 方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!