C#中控制執行緒池的執行順序
阿新 • • 發佈:2018-12-26
在使用執行緒池時,當用執行緒池執行多個任務時,由於執行的任務時間過長,會導制兩個任務互相執行,如果兩個任務具有一定的操作順序,可能會導制不同的操作結果,這時,就要將執行緒池按順序操作。下面先給一段程式碼,該程式碼是不按順序對執行緒池進行操作的,程式碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { AutoResetEvent autoEvent = new AutoResetEvent(false); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod), autoEvent); ThreadPool.QueueUserWorkItem(new WaitCallback(WorkMethod), autoEvent); Console.ReadLine(); } static void ThreadMethod(object stateInfo) { for (int i = 0; i < 100;i++ ) Console.WriteLine("ThreadOne, executing ThreadMethod, " + "is {0}from the thread pool.", Thread.CurrentThread.IsThreadPoolThread ? "" : "not "); } static void WorkMethod(object stateInfo) { for (int i = 0; i < 100; i++) Console.WriteLine("ThreadTwo, executing WorkMethod"); } } }
執行結果如圖1、圖2所示。
圖1 執行結果的上半部
圖2 執行結果的下半部
從圖1、圖2可以看出,在使用執行緒池對執行緒進行操作時,由於各任務的時間過長,多個任務的執行緒可能會互動操作,那麼,如何才能將執行緒池按指定的順序進行操作呢?主要是用AutoResetEvent類來實現的。
可以用AutoResetEvent類的WaitOne方法阻止執行緒,然後只執行當前操作的執行緒池,當遇到AutoResetEvent類的Set方法後,將當前執行緒設定為終止狀態,執行其他等待的執行緒。修改後的程式碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { AutoResetEvent autoEvent = new AutoResetEvent(false); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod), autoEvent); autoEvent.WaitOne(); ThreadPool.QueueUserWorkItem(new WaitCallback(WorkMethod), autoEvent); autoEvent.WaitOne(); Console.ReadLine(); } static void ThreadMethod(object stateInfo) { for (int i = 0; i < 100;i++ ) Console.WriteLine("ThreadOne, executing ThreadMethod, " + "is {0}from the thread pool.", Thread.CurrentThread.IsThreadPoolThread ? "" : "not "); ((AutoResetEvent)stateInfo).Set(); } static void WorkMethod(object stateInfo) { for (int i = 0; i < 100; i++) Console.WriteLine("ThreadTwo, executing WorkMethod"); ((AutoResetEvent)stateInfo).Set(); } } }
執行結果如下: