有時候,我們創建了多線程,需要知道是否都完成了各自的工作。比如說,開啟了多線程的下載,如何終止所有的線程並且在確保所有線程都終止之后才繼續執行程序的退出呢?
1 public partial class MainWindow : Window 2 { 3 public MainWindow() 4 { 5 InitializeComponent(); 6 } 7 8 private volatile bool isContinue = false; 9 static List<WaitHandle> waitHandles = new List<WaitHandle>(); 10 11 private void Button_ThreadStart_Click(object sender, RoutedEventArgs e) 12 { 13 if (isContinue) 14 return; 15 16 isContinue = true; 17 18 Thread t = new Thread(TestWaitAll);//先開啟一個線程 19 t.Name = "TestWaitAll"; 20 t.Start(); 21 } 22 23 private void Button_ThreadStop_Click(object sender, RoutedEventArgs e) 24 { 25 isContinue = false; 26 } 27 28 public void TestWaitAll() 29 { 30 for (int i = 0; i < 5; i++) 31 {
//WaitHandle是一個抽像類別所以得實體化它的子類,也就是 ManualResetEvent 類 或 AutoResetEvent 類 32 ManualResetEvent wh = new ManualResetEvent(false); 33 waitHandles.Add(wh); 34 ThreadPool.QueueUserWorkItem(Task, wh); 35 } 36 WaitHandle.WaitAll(waitHandles.ToArray()); 37 38 Console.WriteLine("所有線程都終止!!!!!!"); 39 MessageBox.Show("搞定!"); 40 } 41 42 public void Task(Object state) 43 { 44 ManualResetEvent mre = (ManualResetEvent)state; 45 while (isContinue) 46 { 47 Console.WriteLine("{0} : {1}", mre.Handle.ToString(), DateTime.Now.ToLongTimeString()); 48 Thread.Sleep(1000); 49 } 50 Console.WriteLine("當前線程終止"); 51 mre.Set(); 52 } 53 }
如果不開啟線程而是直接在UI線程調用TestWaitAll(),就會有異常
WaitHandle.WaitAll(waitHandles),主線程乖乖等待所有線程完成工作
WaitHandle.WaitAll(waitHandles,2000),設定等待時間,表示主線程願意等待子線程執行兩秒鍾
WaitHandle.WaitAny,就是等待任何一線程完成工作
參考:
Thread執行循環的順序啟動WaitHandle.WaitAll方法