自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

.NET 4多核并行中的Task優(yōu)化線程池

開發(fā) 后端
今天我們將介紹的是.NET 4多核并行中的Task優(yōu)化線程池,這也是比較基礎(chǔ)的部分,希望對大家有所幫助。

閱讀本篇前,讀者需對.NET4 System.Threading.Tasks 以及 Task Schedulers 有一定的了解。如果不是很了解,請查閱以下相關(guān)信息:

Task: http://msdn.microsoft.com/en-us/library/system.threading.tasks.task%28VS.100%29.aspx

Task Schedulers: http://msdn.microsoft.com/en-us/library/dd997402.aspx

首先回顧相關(guān)場景:最近工作需要一直在.NET4下編寫window service。在WindowsService下使用了多線程相關(guān)技術(shù)。期間就用了到了線程池。使用線程池的目的:在系統(tǒng)中進(jìn)行多線程并發(fā)也擔(dān)心并發(fā)數(shù)量太大影響性能。于是使用線程池進(jìn)行排隊(duì)。一批一批執(zhí)行多線程。當(dāng)我在使用傳統(tǒng)的.NET線程池的過程中碰見了一些問題,請看以下代碼:

  1. try 
  2.     {  
  3.       ThreadPool.SetMaxThreads(2, 2);   
  4. for (int i = 0; i < 5; i++)  
  5.              {  
  6. ThreadPool.QueueUserWorkItem(new WaitCallback(InvokeThread1), i);   
  7.         }   
  8.      }  
  9.   catch 
  10.      {  
  11.       Console.WriteLine("error");  
  12.  } 

這里建立一個(gè)同時(shí)2個(gè)線程并發(fā)的線程池。在上述代碼第7行傳入InvokeThread1方法:

  1. static void InvokeThread1(object obj)        {                  
  2. throw new NullReferenceException();       
  3.    } 

假設(shè)程序發(fā)生異常,這個(gè)異常卻讓整個(gè)程線程池序崩潰了。主程序并未catch到這個(gè)exception。也許您會說這本來就是這樣的嘛,有什么好貼出來的。但是在.NET4中我們可以避免掉這個(gè)問題。(此時(shí)體現(xiàn)出.NET4的異常強(qiáng)大)。還有個(gè)問題有必要提到:如果一次有兩個(gè)線程同時(shí)并發(fā)(一共要執(zhí)行5個(gè)線程,每次并發(fā)2個(gè))。假設(shè)其中一個(gè)線程執(zhí)行過程中出現(xiàn)了異常,要讓這兩個(gè)線程以外的三個(gè)線程都停止運(yùn)行,來節(jié)省系統(tǒng)資源。傳統(tǒng)的線程池也許可以做到,但是控制起來估計(jì)不會讓你太輕松。但是在.NET4的Task機(jī)制中,這些都得到了妥善的解決,現(xiàn)將以上兩個(gè)問題解決方案給出。如果存在不足的地方,請您指出。

一、自定義TaskScheduler

TaskScheduler代碼如下:

自定義TaskScheduler

  1.  //自定義TaskScheduler  
  2.      public class CustomTaskScheduler : TaskScheduler, IDisposable   
  3.  {   
  4.    //調(diào)用Task的線程  
  5.   Thread[] _Threads;   
  6.  //Task Collection  
  7.      BlockingCollection<Task> _Tasks = new BlockingCollection<Task>();   
  8.       int _ConcurrencyLevel;  
  9. //設(shè)置schedule并發(fā)  
  10.        public CustomTaskScheduler(int concurrencyLevel)  
  11.       {  
  12.             _Threads = new Thread[concurrencyLevel];  
  13.           this._ConcurrencyLevel = concurrencyLevel;  
  14.          for (int i = 0; i < concurrencyLevel; i++)  
  15.          {  
  16.            _Threads[i] = new Thread(() =>  
  17.               {  
  18.                foreach (Task task in _Tasks.GetConsumingEnumerable())  
  19.                         this.TryExecuteTask(task);27   
  20.                });  
  21.                 _Threads[i].Start();  
  22.            }  
  23. }  
  24.         protected override void QueueTask(Task task)  
  25.       {  
  26.          _Tasks.Add(task);  
  27.      }  
  28. protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)  
  29.    {  
  30.        if (_Threads.Contains(Thread.CurrentThread)) return TryExecuteTask(task);  
  31.          return false;  
  32. }  
  33. public override int MaximumConcurrencyLevel50         {  
  34.         get 
  35.         {  
  36.              return _ConcurrencyLevel;54             }  
  37.      }  
  38. protected override IEnumerable<Task> GetScheduledTasks()  
  39.       {  
  40.            return _Tasks.ToArray();  
  41.     }  
  42. public void Dispose()  
  43.       {  
  44.       this._Tasks.CompleteAdding();  
  45.         foreach (Thread t in _Threads)  
  46.           {  
  47.         t.Join();  
  48.           }  
  49.         }  
  50.     } 

該scheduler代碼很簡單,重寫相關(guān)System.Threading.Tasks.TaskScheduler類下的相關(guān)方法即可,代碼中已給出相關(guān)注釋。

二、使用自定義的TaskScheduler

調(diào)用TaskScheduler代碼:

  1. List<string> listMsg = new List<string>() { "Task1""Task2""Task3""Task4""Task5""Task6" };  
  2.            List<Task> listTask = new List<Task>();   
  3.          foreach (string msg in listMsg)  
  4.            {   
  5.         Task myTask = new Task(obj => InvokeThread2((string)obj), msg, token);  
  6.             listTask.Add(myTask);   
  7.              myTask.Start(customTaskScheduler);   
  8.     }  
  9.            try 
  10.        {  
  11.               //等待所有線程全部運(yùn)行結(jié)束  
  12.           Task.WaitAll(listTask.ToArray());  
  13.           }  
  14.          catch (AggregateException ex)  
  15.             {  
  16.             //.NET4 Task的統(tǒng)一異常處理機(jī)制  
  17.           foreach (Exception inner in ex.InnerExceptions)  
  18.               {  
  19.                    Console.WriteLine("Exception type {0} from {1}",  
  20.                   inner.GetType(), inner.Source);  
  21.           }  
  22.           }  
  23.           Console.ReadLine(); 

InvokeThread2 相關(guān)代碼:

  1. static void InvokeThread2(string msg)         
  2.  {          
  3.     try         
  4.      {                  
  5. var x = Convert.ToInt32(msg.Replace("Task""").Trim());                 
  6.  Console.WriteLine(msg);                  
  7. Thread.Sleep(1000 * 5);                 
  8.  Console.WriteLine("{0} ok", msg);            }             
  9.  catch (Exception ex)            
  10.   {                
  11.   //如果有異常發(fā)生則取消正在排隊(duì)的所有線程。          
  12.       tokenSource.Cancel();                 
  13.  Exception exception = new Exception("error");               
  14.    exception.Source = msg;           
  15.        throw exception;            
  16.   }        } 

以上代碼運(yùn)行效果如下:

接著在TaskScheduler調(diào)用代碼中如果將第一行代碼listMsg值修改成 List<string> listMsg = new List<string>() { "Task1", "Task2", "TaskA", "Task3", "Task4", "Task5", "Task6", "Task7", "Task8", "Task9" };這時(shí)候我們將得到以下結(jié)果:

這個(gè)運(yùn)行結(jié)果重點(diǎn)要強(qiáng)調(diào)的地方為:后面這7個(gè)exception。聰明的您或許已經(jīng)看出來前6個(gè)exception屬于沒有執(zhí)行的"Task4", "Task5", "Task6", "Task7", "Task8", "Task9",而最后一個(gè)exception才是真正的發(fā)生異常的"TaskA"。這里主要用到了Task的統(tǒng)一異常處理機(jī)制AggregateException。可以從運(yùn)行結(jié)果得到:Task1,Task2,Task3執(zhí)行成功了,但是TaskA發(fā)生了異常導(dǎo)致了后面排隊(duì)的"Task4", "Task5", "Task6", "Task7", "Task8", "Task9"都不會執(zhí)行了。節(jié)省了系統(tǒng)資源,同時(shí)也提高了系統(tǒng)性能。

三、小結(jié)

本文主要用到了的是.NET4 的Task相關(guān)技術(shù),Task讓我們在多核并行控制的時(shí)候更加簡單,功能更加強(qiáng)大。如果需進(jìn)一步了解相關(guān)技術(shù),博客園已經(jīng)有不少教程。微軟的MSDN也提供了很多參考資料。 最后希望本文可以給您的開發(fā)帶來幫助。

原文鏈接:http://www.cnblogs.com/ryanding/archive/2011/03/22/1990799.html

【編輯推薦】

  1. 微軟發(fā)布新版Windows 7及.NET 4軟件開發(fā)工具包
  2. 詳解.NET 4.0并行計(jì)算支持歷史
  3. 詳讀.NET 4.0環(huán)境配置
  4. 詳解.NET 4.0中異常處理方面的新特性
  5. 三方面詮釋.NET 4.0的新特性
責(zé)任編輯:彭凡 來源: 博客園
相關(guān)推薦

2010-06-08 08:41:08

.NET 4并行編程

2010-06-07 08:43:46

.NET 4并行編程

2010-06-04 09:11:10

.NET并行編程

2010-06-11 09:01:02

.NET 4并行編程

2010-06-09 09:18:34

.NET 4并行編程

2025-02-24 00:00:10

.NET線程池模型

2025-04-28 00:55:00

2013-12-18 17:29:10

多核并行

2010-11-29 08:57:20

Visual Stud.NET 4

2009-06-03 15:27:07

CPU網(wǎng)絡(luò)優(yōu)化網(wǎng)康

2010-06-02 08:53:51

.NET 4并行編程

2024-10-07 08:37:32

線程池C#管理機(jī)制

2013-12-18 16:12:26

多核編程

2024-09-29 16:22:18

多線程TaskC#

2024-09-27 19:42:09

工具C#Task?

2024-04-02 08:52:50

.NETValueTaskTask

2011-11-08 16:31:10

Java

2022-05-31 10:51:12

架構(gòu)技術(shù)優(yōu)化

2009-09-03 09:57:59

Visual StudVS 2010

2023-10-12 08:29:06

線程池Java
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號