当我们在使用线程中,你会发现主线结束后子线程的结果才显示出来。现在我要等待所以子线程结束,然后在显示结果,怎么做呢?
方法如下:
1、使用 ManualResetEvent,代码如下:
using System.Threading; namespace ThreadStudy { /// <summary> /// 等待所有子线程结束 /// </summary> class StopAllWaitBySubThread { List<ManualResetEvent> manualEvents = new List<ManualResetEvent>(); public void Main() { for (int i = 0; i < 5; i++) { ManualResetEvent mre = new ManualResetEvent(false); manualEvents.Add(mre); ThreadPool.QueueUserWorkItem(ThreadMethod, mre); } WaitHandle.WaitAll(manualEvents.ToArray()); Console.WriteLine("Thread Finished!"); } private void ThreadMethod(object obj) { //等待2秒,用于模拟系统在处理事情 Thread.Sleep(2000); ManualResetEvent mre = (ManualResetEvent)obj; mre.Set(); Console.WriteLine("Thread execute"); } } }
此种方法线程中只传递了信号,那要传递参数怎么办?可以采用类,将信号放在类中来解决,代码如下。
using System.Threading; namespace ThreadStudy { /// <summary> /// 等待所有子线程结束 /// </summary> class StopAllWaitBySubThread { List<ManualResetEvent> manualEvents = new List<ManualResetEvent>(); public void Main() { for (int i = 0; i < 5; i++) { ManualResetEvent mre = new ManualResetEvent(false); manualEvents.Add(mre); Param pra = new Param(); pra.mrEvent = mre; pra.praData = i; ThreadPool.QueueUserWorkItem(ThreadMethod, pra); } WaitHandle.WaitAll(manualEvents.ToArray()); Console.WriteLine("Thread Finished!"); } private void ThreadMethod(object obj) { Thread.Sleep(2000); Param pra = (Param)obj; pra.mrEvent.Set(); Console.WriteLine("Thread execute at {0}", pra.praData); } } public class Param { public ManualResetEvent mrEvent; public int praData; } }
2、判断线程数
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ThreadStudy { /// <summary> /// 判断当所有子线程执行完毕 /// </summary> class ThreadPoolStop { public void Main() { for (int i = 0; i < 5; i++) { ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod), i); } int maxWorkerThreads, workerThreads; int portThreads; while (true) { /* GetAvailableThreads():检索由 GetMaxThreads 返回的线程池线程的最大数目和当前活动数目之间的差值。 而GetMaxThreads 检索可以同时处于活动状态的线程池请求的数目。 通过最大数目减可用数目就可以得到当前活动线程的数目,如果为零,那就说明没有活动线程,说明所有线程运行完毕。 */ ThreadPool.GetMaxThreads(out maxWorkerThreads, out portThreads); ThreadPool.GetAvailableThreads(out workerThreads, out portThreads); if (maxWorkerThreads - workerThreads == 0) { Console.WriteLine("Thread Finished!"); break; } } } private void ThreadMethod(object i) {
//模拟程序运行
Thread.Sleep((new Random().Next(1, 4)) * 1000); Console.WriteLine("Thread execute at {0}", i.ToString()); } } }
3、使用Monitor
using System.Threading; namespace ThreadStudy { class StopAllSubThread { int _ThreadCount = 5; int finishcount = 0; object locker = new object(); public void Main() { for (int i = 0; i < _ThreadCount; i++) { Thread trd = new Thread(new ParameterizedThreadStart(ThreadMethod)); trd.Start(i); } lock (locker) { while (finishcount != _ThreadCount) { Monitor.Wait(locker);//等待 } } Console.WriteLine("Thread Finished!"); } private void ThreadMethod(object obj) { //模拟执行程序 Thread.Sleep(3000); Console.WriteLine("Thread execute at {0}", obj.ToString()); lock (locker) { finishcount++; Monitor.Pulse(locker); //完成,通知等待队列,告知已完,执行下一个。 } } } }