C# 多線程--線程池的詳細介紹

來源:互聯網
上載者:User
程池System.Threading.ThreadPool,可用於發送工作項目、處理非同步I/O、代表其它線程等待以及處理計時器。基本用法:

        public void Main()        {            ThreadPool.QueueUserWorkItem(JobForAThread); // 將某工作交給線程池}void JobForAThread(object state) // 線程要執行的工作:滿足 委託WaitCallback        {for (int i = 1; i <= 5; i++)            {                Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i);                Thread.Sleep(500);            }        }

在執行 ThreadPool.QueueUserWorkItem() 方法後,處理器就會自動在池中選擇一個線程來處理“工作內容”。

1.如果線程池還沒有運行,就會建立一個線程池,並啟動第一個線程。

2.如果線程池已經在運行,且至少有一個閒置線程,線程池就會把改“工作內容”交給這個閒置線程來處理。

3.如果當時線程池沒有閒置線程,該工作就會處於等待狀態,直到有空閑線程來處理它。

過 ThreadPool.GetMaxThreads() 方法來 檢索可以同時處於活動狀態的線程池請求的數目。

            int vWorkerThreads; int vCompletionPortThreads;            ThreadPool.GetMaxThreads(out vWorkerThreads, out vCompletionPortThreads);            Console.WriteLine("池中輔助線程的最大數{0},池中非同步 I/O 線程的最大數{1}", vWorkerThreads, vCompletionPortThreads);

可以通過 ThreadPool.SetMaxThreads() 方法設定可以同時處於活動狀態的線程池請求的數目。

ThreadPool.SetMaxThreads(5, 4);

但是,不能將輔助線程的數目或非同步I/O完成線程的數目設定位 小於 電腦處理器的數目。線程池使用很簡單,但又一些限制:

1.線程池中的所有線程都是後台線程。如果進程的所有前台線程都結束了,所有後台線程就會停止。不能把入池的線程改為前台線程。

2.不能給入池的線程設定優先權或名稱。

3.入池的線程只能用於時間較短的任務。如果線程要一直運行,就應該使用Thread類建立一個線程。

JobForAThread() 工作任務傳遞參數 object state,調用:

        public void Main()        {            ThreadPool.QueueUserWorkItem(JobForAThread,"這是傳遞給工作內容的參數"); // 添加工作的同時,傳遞參數Console.ReadKey(); // 讓主線程等待,否則“一閃而過”        }void JobForAThread(object state)         {            Console.WriteLine("收到資訊:{0}", (string)state); // 處理傳進來的資料for (int i = 1; i <= 5; i++)            {                               Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i);                Thread.Sleep(500);            }        }

簡單的控制操作

般情況下,“工作”交給線程池後,就不受控制了, 它會由處理器自動決定什麼時候開始執行(當然是有空閑線程才行)。可以通過以下代碼,讓工作在指定時候以後再開始執行。

        ManualResetEvent mManualEvent;public void Main()        {            mManualEvent = new ManualResetEvent(false); // 執行個體ThreadPool.QueueUserWorkItem(JobForAThread);            Console.WriteLine("{0} 任務已經交給線程池了,但是它沒有執行.", DateTime.Now.ToString("HH:mm:ss"));            Thread.Sleep(10000); // 等待 10smManualEvent.Set();  // 發出訊號,讓線程繼續執行                       Console.ReadKey(); // 讓主線程等待,否則“一閃而過”        }void JobForAThread(object state)         {            mManualEvent.WaitOne(); // 等待 “ mManualEvent.Set();” 這一句執行(發送訊號)Console.WriteLine("{0} 現在開始執行任務啦.", DateTime.Now.ToString("HH:mm:ss"));for (int i = 1; i <= 5; i++)            {                               Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i);                Thread.Sleep(500);            }        }

運行結果:

這裡在將工作交給線程池後,線程執行工作時,一直阻塞在 mManualEvent.WaitOne(); 這一句,直到10s後主線程發出了訊號,該工作才繼續執行後續代碼。這是一種“假開始”控制操作,本質上並沒有實現讓指定工作在希望的時候開始工作。這裡 在初始化 ManualResetEvent 對象時參數 false 表示,預設將訊號置為“阻塞狀態”,通過代碼 mManualEvent.Set(); 將訊號置為“可繼續狀態”。反之,可以通過代碼 mManualEvent.Reset(); 將線程置為“阻塞狀態”。

時,需要等待所有線程池中的線程執行完成後,才繼續執行其它某些代碼。

        AutoResetEvent[] mAutoResetEvent;public void Main()        {            mAutoResetEvent = new AutoResetEvent[]{new AutoResetEvent(false), // 預設訊號為 阻塞new AutoResetEvent(false),new AutoResetEvent(false)            };for (int i = 0; i < 3; i++) // 建立3個工作            {                Thread.Sleep(1000);                ThreadPool.QueueUserWorkItem(JobForAThread, i);             }            Console.WriteLine("所有工作已經添加到池中...");            WaitHandle.WaitAll(mAutoResetEvent); // 等待 mAutoResetEvent 中所有訊號變為 繼續 後,繼續後面代碼Console.WriteLine("所有工作已經完成了");            Console.ReadKey(); // 讓主線程等待,否則“一閃而過”        }void JobForAThread(object state)         {int vJobIndex = (int)state;            Console.WriteLine("Job {0} Started.", vJobIndex);for (int i = 1; i <= 5; i++)            {                Console.WriteLine("Running Thread {0},Step {1},Job {2} ", Thread.CurrentThread.ManagedThreadId, i, vJobIndex);                Thread.Sleep(500);            }            mAutoResetEvent[vJobIndex].Set();        }

運行結果:

[]

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.