C#多線程學習 之 線程池[ThreadPool]

來源:互聯網
上載者:User
文章目錄
  • ThreadPool.SetMaxThreads 方法

在多線程的程式中,經常會出現兩種情況:

一種情況:   應用程式中,線程把大部分的時間花費在等待狀態,等待某個事件發生,然後才能給予響應
                  這一般使用ThreadPool(線程池)來解決;

另一種情況:線程平時都處於休眠狀態,只是周期性地被喚醒
                  這一般使用Timer(定時器)來解決;

本篇文章單單講線程池[ThreadPool]

ThreadPool類 MSDN協助資訊: http://msdn.microsoft.com/zh-cn/library/system.threading.threadpool.aspx#Y0

將任務添加進線程池:

ThreadPool.QueueUserWorkItem(new WaitCallback(方法名));

重載

ThreadPool.QueueUserWorkItem(new WaitCallback(方法名), 參數);

因為ThreadPool是靜態類 所以不需要執行個體化.

 

對於線程池主要的控制有控制線程數大小:

ThreadPool.SetMaxThreads 方法
public static bool SetMaxThreads(int workerThreads,int completionPortThreads)

參數:

workerThreads
類型:System.Int32

線程池中輔助線程的最大數目。

completionPortThreads
類型:System.Int32

線程池中非同步 I/O 線程的最大數目。

例子:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace 多線程池實驗{    class Program    {        public static void Main()        {            ThreadPool.SetMaxThreads(3, 3);            for (int i = 0; i < 50; i++)            {                thr t = new thr();                ThreadPool.QueueUserWorkItem(new WaitCallback(t.ThreadProc), i);            }            Console.WriteLine("斷點測試");            Thread.Sleep(100000);            Console.WriteLine("運行結束");        }        public class thr        {            public void ThreadProc(object i)            {                Console.WriteLine("Thread[" + i.ToString() + "]");                Thread.Sleep(1000);            }        }    }}

輸出結果:

您會發現 斷點測試 在上面了, 這是什麼原因呢?

原因:

1. 線程池的啟動和終止不是我們程式所能控制的, 我反正是不知道的, 你如果知道的話 可以發郵件給我 henw@163.com

2. 線程池中的線程執行完之後是沒有傳回值的.

總之一句話, 我們不知道線程池他幹了什麼, 那麼我們該怎麼解決 任務完成問題呢?

作業系統提供了一種”號誌”(ManualResetEvent)

ManualResetEvent 允許線程通過發訊號互相通訊。通常,此通訊涉及一個線程在其他線程進行之前必須完成的任務。當一個線程開始一個活動(此活動必須完成後,其他線程才能開始)時,它調用 Reset 以將 ManualResetEvent 置於非終止狀態,此線程可被視為控制 ManualResetEvent。調用 ManualResetEvent 上的 WaitOne 的線程將阻止,並等待訊號。當控制線程完成活動時,它調用 Set 以發出等待線程可以繼續進行的訊號。並釋放所有等待線程。一旦它被終止,ManualResetEvent 將保持終止狀態(即對 WaitOne 的調用的線程將立即返回,並不阻塞),直到它被手動重設。可以通過將布爾值傳遞給建構函式來控制 ManualResetEvent 的初始狀態,如果初始狀態處於終止狀態,為 true;否則為 false。

詳細見MSDN: http://msdn.microsoft.com/zh-cn/library/system.threading.manualresetevent.aspx

主要使用了

eventX.WaitOne(Timeout.Infinite, true);  阻止當前線程,直到當前 WaitHandle 收到訊號為止。

eventX.Set(); 將事件狀態設定為終止狀態,允許一個或多個等待線程繼續。

修改後的程式:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace 多線程池實驗{    class Program    {        public static void Main()        {            //建立ManualResetEvent對象並且初始化為無訊號狀態            ManualResetEvent eventX = new ManualResetEvent(false);            ThreadPool.SetMaxThreads(3, 3);            thr t = new thr(15, eventX);            for (int i = 0; i < 15; i++)            {                ThreadPool.QueueUserWorkItem(new WaitCallback(t.ThreadProc), i);            }            //等待事件的完成,即線程調用ManualResetEvent.Set()方法            //eventX.WaitOne  阻止當前線程,直到當前 WaitHandle 收到訊號為止。             eventX.WaitOne(Timeout.Infinite, true);            Console.WriteLine("斷點測試");            Thread.Sleep(10000);            Console.WriteLine("運行結束");        }        public class thr        {            public thr(int count,ManualResetEvent mre)            {                iMaxCount = count;                eventX = mre;            }            public static int iCount = 0;            public static int iMaxCount = 0;            public ManualResetEvent eventX;            public void ThreadProc(object i)            {                Console.WriteLine("Thread[" + i.ToString() + "]");                Thread.Sleep(2000);                //Interlocked.Increment()操作是一個原子操作,作用是:iCount++ 具體請看下面說明                 //原子操作,就是不能被更高等級中斷搶奪優先的操作。你既然提這個問題,我就說深一點。                //由於作業系統大部分時間處於開中斷狀態,                //所以,一個程式在執行的時候可能被優先順序更高的線程中斷。                //而有些操作是不能被中斷的,不然會出現無法還原的後果,這時候,這些操作就需要原子操作。                //就是不能被中斷的操作。                Interlocked.Increment(ref iCount);                if (iCount == iMaxCount)                {                    Console.WriteLine("發出結束訊號!");                    //將事件狀態設定為終止狀態,允許一個或多個等待線程繼續。                    eventX.Set();                }            }        }    }}

輸出結果:

順序正常了.

程式源碼: 多線程池實驗.zip

歡迎大家一起探討!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.