日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

C# ThreadPool类(线程池)

發布時間:2025/7/25 125 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# ThreadPool类(线程池) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

地址:https://www.cnblogs.com/scmail81/archive/2018/08/19/9503266.html

?

?

CLR線程池并不會在CLR初始化時立即建立線程,而是在應用程序要創建線程來運行任務時,線程池才初始化一個線程。
線程池初始化時是沒有線程的,線程池里的線程的初始化與其他線程一樣,但是在完成任務以后,該線程不會自行銷毀,而是以掛起的狀態返回到線程池。直到應用程序再次向線程池發出請求時,線程池里掛起的線程就會再度激活執行任務。
這樣既節省了建立線程所造成的性能損耗,也可以讓多個任務反復重用同一線程,從而在應用程序生存期內節約大量開銷。

通過CLR線程池所建立的線程總是默認為后臺線程,優先級數為ThreadPriority.Normal。

CLR線程池分為工作者線程(workerThreads)I/O線程(completionPortThreads)兩種:

  • 工作者線程是主要用作管理CLR內部對象的運作,通常用于計算密集的任務。
  • I/O(Input/Output)線程主要用于與外部系統交互信息,如輸入輸出,CPU僅需在任務開始的時候,將任務的參數傳遞給設備,然后啟動硬件設備即可。等任務完成的時候,CPU收到一個通知,一般來說是一個硬件的中斷信號,此時CPU繼續后繼的處理工作。在處理過程中,CPU是不必完全參與處理過程的,如果正在運行的線程不交出CPU的控制權,那么線程也只能處于等待狀態,即使操作系統將當前的CPU調度給其他線程,此時線程所占用的空間還是被占用,而并沒有CPU處理這個線程,可能出現線程資源浪費的問題。如果這是一個網絡服務程序,每一個網絡連接都使用一個線程管理,可能出現大量線程都在等待網絡通信,隨著網絡連接的不斷增加,處于等待狀態的線程將會很消耗盡所有的內存資源。可以考慮使用線程池解決這個問題。

  線程池的最大值一般默認為1000、2000。當大于此數目的請求時,將保持排隊狀態,直到線程池里有線程可用。

  使用CLR線程池的工作者線程一般有兩種方式:

  • 通過ThreadPool.QueueUserWorkItem()方法;
  • 通過委托;

  要注意,不論是通過ThreadPool.QueueUserWorkItem()還是委托,調用的都是線程池里的線程。

通過以下兩個方法可以讀取和設置CLR線程池中工作者線程與I/O線程的最大線程數。

  • ThreadPool.GetMax(out in workerThreads,out int completionPortThreads);
  • ThreadPool.SetMax(int workerThreads,int completionPortThreads);
  •   若想測試線程池中有多少線程正在投入使用,可以通過ThreadPool.GetAvailableThreads(out in workThreads,out int conoletionPortThreads)方法。

    方法說明
    GetAvailableThreads剩余空閑線程數
    GetMaxThreads最多可用線程數,所有大于此數目的請求將保持排隊狀態,直到線程池線程變為可用
    GetMinThreads檢索線程池在新請求預測中維護的空閑線程數
    QueueUserWorkItem啟動線程池里得一個線程(隊列的方式,如線程池暫時沒空閑線程,則進入隊列排隊)
    SetMaxThreads設置線程池中的最大線程數
    SetMinThreads設置線程池最少需要保留的線程數

    我們可以使用線程池來解決上面的大部分問題,跟使用單個線程相比,使用線程池有如下優點:

    1、縮短應用程序的響應時間。因為在線程池中有線程的線程處于等待分配任務狀態(只要沒有超過線程池的最大上限),無需創建線程。

    2、不必管理和維護生存周期短暫的線程,不用在創建時為其分配資源,在其執行完任務之后釋放資源。

    3、線程池會根據當前系統特點對池內的線程進行優化處理。

    總之使用線程池的作用就是減少創建和銷毀線程的系統開銷。在.NET中有一個線程的類ThreadPool,它提供了線程池的管理。

    ThreadPool是一個靜態類,它沒有構造函數,對外提供的函數也全部是靜態的。其中有一個QueueUserWorkItem方法,它有兩種重載形式,如下:

    public static bool QueueUserWorkItem(WaitCallback callBack):將方法排入隊列以便執行。此方法在有線程池線程變得可用時執行。

    public static bool QueueUserWorkItem(WaitCallback callBack,Object state):將方法排入隊列以便執行,并指定包含該方法所用數據的對象。此方法在有線程池線程變得可用時執行。

    QueueUserWorkItem方法中使用的的WaitCallback參數表示一個delegate,它的聲明如下:

    public delegate void WaitCallback(Object state)

    如果需要傳遞任務信息可以利用WaitCallback中的state參數,類似于ParameterizedThreadStart委托。

    下面是一個ThreadPool的例子,代碼如下:

    using System; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Threading;namespace ConsoleApp1 {class ThreadPoolDemo{public ThreadPoolDemo(){}public void Work(){ThreadPool.QueueUserWorkItem(new WaitCallback(CountProcess));ThreadPool.QueueUserWorkItem(new WaitCallback(GetEnvironmentVariables));}/// <summary> /// 統計當前正在運行的系統進程信息 /// </summary> /// <param name="state"></param> private void CountProcess(object state){Process[] processes = Process.GetProcesses();foreach (Process p in processes){try{Console.WriteLine("進程信息:Id:{0},ProcessName:{1},StartTime:{2}", p.Id, p.ProcessName, p.StartTime);}catch (Win32Exception e){Console.WriteLine("ProcessName:{0}", p.ProcessName);}finally{}}Console.WriteLine("獲取進程信息完畢。");}/// <summary> /// 獲取當前機器系統變量設置 /// </summary> /// <param name="state"></param> public void GetEnvironmentVariables(object state){IDictionary list = System.Environment.GetEnvironmentVariables();foreach (DictionaryEntry item in list){Console.WriteLine("系統變量信息:key={0},value={1}", item.Key, item.Value);}Console.WriteLine("獲取系統變量信息完畢。");}} } using System; using System.Threading;namespace ConsoleApp1 {class Program{static void Main(string[] args){ThreadPoolDemo tpd1 = new ThreadPoolDemo();tpd1.Work();Thread.Sleep(5000);Console.WriteLine("OK");Console.ReadLine();}} }

    轉載于:https://www.cnblogs.com/zxtceq/p/10980480.html

    總結

    以上是生活随笔為你收集整理的C# ThreadPool类(线程池)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。