ThreadPool&ManualResetEvent

在多線程的程序中,常常會出現兩種狀況:多線程

一種狀況: 應用程序中,線程把大部分的時間花費在等待狀態,等待某個事件發生,而後才能給予響應函數

這通常使用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代理對象,而線程的創建、管理、運行等工做都是由系統自動完成的,你無須考慮那些複雜的細節問題。

ThreadPool 的用法:

首先程序建立了一個ManualResetEvent對象,該對象就像一個信號燈,能夠利用它的信號來通知其它線程。

本例中,當線程池中全部線程工做都完成之後,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");
        }
    }
}
本站公眾號
   歡迎關注本站公眾號,獲取更多信息