C#並行和多線程編程

來源:互聯網
上載者:User

標籤:

5天玩轉C#並行和多線程編程系列文章目錄

5天玩轉C#並行和多線程編程 —— 第一天 認識Parallel

5天玩轉C#並行和多線程編程 —— 第二天 並行集合和PLinq

5天玩轉C#並行和多線程編程 —— 第三天 認識和使用Task

5天玩轉C#並行和多線程編程 —— 第四天 Task進階

5天玩轉C#並行和多線程編程 —— 第五天 多線程編程大總結

在上一篇部落格5天玩轉C#並行和多線程編程 —— 第一天 認識Parallel中,我們學習了Parallel的用法。並行編程,本質上是多線程的編程,那麼當多個線程同時處理一個任務的時候,必然會出現資源訪問問題,及所謂的安全執行緒。就像現實中,我們開發項目,就是一個並行的例子,把不同的模組分給不同的人,同時進行,才能在短的時間內做出大的項目。如果大家都只管自己寫自己的代碼,寫完後發現合并不到一起,那麼這種並行就沒有了意義。  並行演算法的出現,隨之而產生的也就有了並行集合,及安全執行緒集合;微軟向的也算周到,沒有忘記linq,也推出了linq的並行版本,plinq - Parallel Linq.   一、並行集合 —— 安全執行緒集合  並行計算使用的多個線程同時進行計算,所以要控制每個線程對資源的訪問,我們先來看一下平時常用的List<T>集合,在並行計算下的表現,建立一個控制台應用程式,添加一個PEnumerable類(當然你也直接寫到main方法裡面測試,建議分開寫),寫如下方法:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Collections.Concurrent;namespace ThreadPool{   public class PEnumerable   {      public static void ListWithParallel()      {         List<int> list = new List<int>();         Parallel.For(0, 10000, item =>         {            list.Add(item);         });         Console.WriteLine("List‘s count is {0}",list.Count());      }   }}

點擊F5運行,得到如下結果:

看到結果中顯示的5851,但是我們迴圈的是10000次啊!怎麼結果不對呢?這是因為List<T>是非安全執行緒集合,意思就是說所有的線程都可以修改他的值。

下面我們來看下並行集合 —— 安全執行緒集合,在System.Collections.Concurrent命名空間中,首先來看一下ConcurrentBag<T>泛型集合,其用法和List<T>類似,先來寫個方法測試一下:

public static void ConcurrentBagWithPallel()      {         ConcurrentBag<int> list = new ConcurrentBag<int>();         Parallel.For(0, 10000, item =>         {            list.Add(item);         });         Console.WriteLine("ConcurrentBag‘s count is {0}", list.Count());      }

同時執行兩個方法,結果如下:

可以看到,ConcurrentBag集合的結果是正確的。下面我們修改代碼看看ConcurrentBag裡面的資料到底是怎麼存放的,修改代碼如下:

public static void ConcurrentBagWithPallel()      {         ConcurrentBag<int> list = new ConcurrentBag<int>();         Parallel.For(0, 10000, item =>         {            list.Add(item);         });         Console.WriteLine("ConcurrentBag‘s count is {0}", list.Count());         int n = 0;         foreach(int i in list)         {            if (n > 10)               break;            n++;            Console.WriteLine("Item[{0}] = {1}",n,i);         }         Console.WriteLine("ConcurrentBag‘s max item is {0}", list.Max());      }

先來看一下運行結果:

可以看到,ConcurrentBag中的資料並不是按照順序排列的,順序是亂的,隨機的。我們平時使用的Max、First、Last等linq方法都還有。其時分類似Enumerable的用法,大家可以參考微軟的MSDN瞭解它的具體用法。

關於安全執行緒的集合還有很多,和我們平時用的集合都差不多,比如類似Dictionary的ConcurrentDictionary,還有ConcurrentStack,ConcurrentQueue等。

 

 二、Parallel Linq的用法及效能

1、AsParallel

前面瞭解了並行的For和foreach,今天就來看一下Linq的並行版本是怎麼樣吧?為了測試,我們添加一個Custom類,代碼如下:

public class Custom   {      public string Name { get; set; }      public int Age { get; set; }      public string Address { get; set; }   }

 寫如下測試代碼:

 public static void TestPLinq()      {         Stopwatch sw = new Stopwatch();         List<Custom> customs = new List<Custom>();         for (int i = 0; i < 2000000; i++)         {            customs.Add(new Custom() { Name = "Jack", Age = 21, Address = "NewYork" });            customs.Add(new Custom() { Name = "Jime", Age = 26, Address = "China" });            customs.Add(new Custom() { Name = "Tina", Age = 29, Address = "ShangHai" });            customs.Add(new Custom() { Name = "Luo", Age = 30, Address = "Beijing" });            customs.Add(new Custom() { Name = "Wang", Age = 60, Address = "Guangdong" });            customs.Add(new Custom() { Name = "Feng", Age = 25, Address = "YunNan" });         }         sw.Start();         var result = customs.Where<Custom>(c => c.Age > 26).ToList();         sw.Stop();         Console.WriteLine("Linq time is {0}.",sw.ElapsedMilliseconds);         sw.Restart();         sw.Start();         var result2 = customs.AsParallel().Where<Custom>(c => c.Age > 26).ToList();         sw.Stop();         Console.WriteLine("Parallel Linq time is {0}.", sw.ElapsedMilliseconds);      }

其實也就是加了一個AsParallel()方法,下面來看下運行結果:

時間相差了一倍,不過有時候不會相差這麼多,要看系統當前的資源使用率。大家可以多測試一下。

其實,AsParallel()這個方法可以應用與任何集合,包括List<T>集合,從而提高查詢速度和系統效能。

 

2、GroupBy方法

在項目中,我們經常要對資料做處理,比如分組統計,我們知道在linq中也可以實現,今天來學習一下新的ToLookup方法,寫一個測試方法,代碼如下:

public static void OrderByTest()      {         Stopwatch stopWatch = new Stopwatch();         List<Custom> customs = new List<Custom>();         for (int i = 0; i < 2000000; i++)         {            customs.Add(new Custom() { Name = "Jack", Age = 21, Address = "NewYork" });            customs.Add(new Custom() { Name = "Jime", Age = 26, Address = "China" });            customs.Add(new Custom() { Name = "Tina", Age = 29, Address = "ShangHai" });            customs.Add(new Custom() { Name = "Luo", Age = 30, Address = "Beijing" });            customs.Add(new Custom() { Name = "Wang", Age = 60, Address = "Guangdong" });            customs.Add(new Custom() { Name = "Feng", Age = 25, Address = "YunNan" });         }         stopWatch.Restart();         var groupByAge = customs.GroupBy(item => item.Age).ToList();         foreach (var item in groupByAge)         {            Console.WriteLine("Age={0},count = {1}", item.Key, item.Count());         }         stopWatch.Stop();         Console.WriteLine("Linq group by time is: " + stopWatch.ElapsedMilliseconds);         stopWatch.Restart();         var lookupList = customs.ToLookup(i => i.Age);         foreach (var item in lookupList)         {            Console.WriteLine("LookUP:Age={0},count = {1}", item.Key, item.Count());         }         stopWatch.Stop();         Console.WriteLine("LookUp group by time is: " + stopWatch.ElapsedMilliseconds);      }

運行結果如下:

ToLookup方法是將集合轉換成一個唯讀集合,所以在大資料量分組時效能優於List.大家可以查閱相關資料,這裡由於篇幅問題,不再細說。

 

 

 

 

 

 

分類: C#

C#並行和多線程編程

聯繫我們

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