首頁 >後端開發 >C#.Net教程 >C# 多執行緒--執行緒池的詳細介紹

C# 多執行緒--執行緒池的詳細介紹

零下一度
零下一度原創
2017-06-24 09:38:152753瀏覽

   程池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);

 執行緒池使用很簡單,但又有一些限制:

  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();
        }
######運行結果:################ ######[]###### ########################################################

以上是C# 多執行緒--執行緒池的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn