在多線程的程序中,常常會出現兩種狀況:多線程
一種狀況: 應用程序中,線程把大部分的時間花費在等待狀態,等待某個事件發生,而後才能給予響應函數
這通常使用ThreadPool(線程池)來解決;spa
另外一種狀況:線程平時都處於休眠狀態,只是週期性地被喚醒線程
這通常使用Timer(定時器)來解決;代理
ThreadPool類提供一個由系統維護的線程池(能夠看做一個線程的容器),該容器須要 Windows 2000 以上系統支持,由於其中某些方法調用了只有高版本的Windows纔有的API函數。對象
將線程安放在線程池裏,需使用ThreadPool.QueueUserWorkItem()方法,該方法的原型以下:blog
//將一個線程放進線程池,該線程的Start()方法將調用WaitCallback代理對象表明的函數事件
public static bool QueueUserWorkItem(WaitCallback);原型
//重載的方法以下,參數object將傳遞給WaitCallback所表明的方法string
public static bool QueueUserWorkItem(WaitCallback, object);
ThreadPool類是一個靜態類,你不能也沒必要要生成它的對象。並且一旦使用該方法在線程池中添加了一個項目,那麼該項目將是沒法取消的。
在這裏你無需本身創建線程,只需把你要作的工做寫成函數,而後做爲參數傳遞給ThreadPool.QueueUserWorkItem()方法就好了,傳遞的方法就是依靠WaitCallback代理對象,而線程的創建、管理、運行等工做都是由系統自動完成的,你無須考慮那些複雜的細節問題。
首先程序建立了一個ManualResetEvent對象,該對象就像一個信號燈,能夠利用它的信號來通知其它線程。
本例中,當線程池中全部線程工做都完成之後,ManualResetEvent對象將被設置爲有信號,從而通知主線程繼續運行。
初始化該對象時,用戶能夠指定其默認的狀態(有信號/無信號);
在初始化之後,該對象將保持原來的狀態不變,直到它的Reset()或者Set()方法被調用:
Reset()方法:將其設置爲無信號狀態;
Set()方法:將其設置爲有信號狀態。
WaitOne()方法:使當前線程掛起,直到ManualResetEvent對象處於有信號狀態,此時該線程將被激活。而後,程序將向線程池中添加工做項,這些以函數形式提供的工做項被系統用來初始化自動創建的線程。當全部的線程都運行完了之後,ManualResetEvent.Set()方法被調用,由於調用了ManualResetEvent.WaitOne()方法而處在等待狀態的主線程將接收到這個信號,因而它接着往下執行,完成後邊的工做。
ThreadPool 的用法示例:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ThreadPool_Test1 { class Program { static ManualResetEvent eventX = new ManualResetEvent(false); static void Main(string[] args) { Console.WriteLine("ThreadID:" + Thread.CurrentThread.ManagedThreadId); ThreadPool.QueueUserWorkItem(new WaitCallback(Jia)); eventX.WaitOne(TimeSpan.FromSeconds(2)); eventX.Reset(); Console.WriteLine("OK"); Console.ReadKey(); } static void Jia(object obj) { Console.WriteLine("ThreadID:"+Thread.CurrentThread.ManagedThreadId); Thread.Sleep(1000); eventX.Set(); Console.WriteLine("Jia"); } } }