最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# 并行和多線程編程——并行集合和PLinq

 更新時間:2021年02月20日 09:21:06   作者:雲(yún)霏霏  
這篇文章主要介紹了C# 并行和多線程編程的相關資料,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下

  在上一篇博客,我們學習了Parallel的用法。并行編程,本質上是多線程的編程,那么當多個線程同時處理一個任務的時候,必然會出現(xiàn)資源訪問問題,及所謂的線程安全。就像現(xiàn)實中,我們開發(fā)項目,就是一個并行的例子,把不同的模塊分給不同的人,同時進行,才能在短的時間內做出大的項目。如果大家都只管自己寫自己的代碼,寫完后發(fā)現(xiàn)合并不到一起,那么這種并行就沒有了意義。
  并行算法的出現(xiàn),隨之而產生的也就有了并行集合,及線程安全集合;微軟向的也算周到,沒有忘記linq,也推出了linq的并行版本,plinq - Parallel Linq. 

一、并行集合 —— 線程安全集合

  并行計算使用的多個線程同時進行計算,所以要控制每個線程對資源的訪問,我們先來看一下平時常用的List<T>集合,在并行計算下的表現(xiàn),新建一個控制臺應用程序,添加一個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,但是我們循環(huán)的是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());
  }

同時執(zhí)行兩個方法,結果如下:

可以看到,ConcurrentBag集合的結果是正確的。下面我們修改代碼看看ConcurrentBag里面的數(shù)據(jù)到底是怎么存放的,修改代碼如下:

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中的數(shù)據(jù)并不是按照順序排列的,順序是亂的,隨機的。我們平時使用的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()方法,下面來看下運行結果:

時間相差了一倍,不過有時候不會相差這么多,要看系統(tǒng)當前的資源利用率。大家可以多測試一下。

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

2、GroupBy方法

在項目中,我們經常要對數(shù)據(jù)做處理,比如分組統(tǒng)計,我們知道在linq中也可以實現(xiàn),今天來學習一下新的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方法是將集合轉換成一個只讀集合,所以在大數(shù)據(jù)量分組時性能優(yōu)于List.大家可以查閱相關資料,這里由于篇幅問題,不再細說。

以上就是C# 并行和多線程編程——并行集合和PLinq的詳細內容,更多關于C# 并行和多線程編程的資料請關注腳本之家其它相關文章!

相關文章

  • 理解C#生成驗證碼的過程

    理解C#生成驗證碼的過程

    這篇文章主要介紹了C#生成驗證碼的過程,通過實例分析C#驗證碼的生成原理,感興趣的小伙伴們可以參考一下
    2016-03-03
  • C#多線程學習之(四)使用線程池進行多線程的自動管理

    C#多線程學習之(四)使用線程池進行多線程的自動管理

    這篇文章主要介紹了C#多線程學習之使用線程池進行多線程的自動管理,實例分析了C#中線程池的概念與相關的使用技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • C#實現(xiàn)獲取設置IP地址小工具

    C#實現(xiàn)獲取設置IP地址小工具

    c# 開發(fā),方便更改IP地址。由于公司和家里的ip設置不一樣,公司要求手動設置,在家可以自動獲取IP,切都是無線網絡,為了方便操作,故做了這個小工具!
    2015-06-06
  • 基于.NET編寫工具類解決JSON亂碼問題

    基于.NET編寫工具類解決JSON亂碼問題

    在開發(fā)過程中,我們經常會遇到JSON數(shù)據(jù)處理的問題,尤其是在數(shù)據(jù)傳輸和解析過程中,很容易出現(xiàn)編碼錯誤導致的亂碼問題,下面我們就來編寫一個.NET工具類來解決這一問題吧
    2025-03-03
  • C# OpenCvSharp實現(xiàn)通過特征點匹配圖片

    C# OpenCvSharp實現(xiàn)通過特征點匹配圖片

    這篇文章主要為大家詳細介紹了C#如何結合OpenCVSharp4實現(xiàn)通過特征點匹配圖片,文中的示例代碼簡潔易懂,具有一定的學習價值,需要的小伙伴可以參考下
    2023-11-11
  • C# 線性插值的實現(xiàn)示例

    C# 線性插值的實現(xiàn)示例

    線性插值是針對一維數(shù)據(jù)的插值方法,本文主要介紹了C# 線性插值的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • C# BeginInvoke實現(xiàn)異步編程方式

    C# BeginInvoke實現(xiàn)異步編程方式

    這篇文章主要介紹了C# BeginInvoke實現(xiàn)異步編程方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • C#中Dictionary泛型集合7種常見的用法

    C#中Dictionary泛型集合7種常見的用法

    本文主要介紹了Dictionary集合的7種最基礎的用法,包括創(chuàng)建、添加、查找、遍歷、刪除等方法,程序都是由簡入繁,希望能通過閱讀簡單的示例,給大家一些啟發(fā)。
    2016-03-03
  • 一文帶你快速學會C#中WinForm框架的使用詳解

    一文帶你快速學會C#中WinForm框架的使用詳解

    WinForm是一門非常經濟實惠的技術,就是說,可以在短時間內學會,并迅速借此進行項目開發(fā)。本文就來和大家聊聊WinForm框架的使用方法,希望對大家有所幫助
    2023-02-02
  • C#中backgroundworker的使用教程

    C#中backgroundworker的使用教程

    這篇文章主要介紹了C#中backgroundworker的使用教程,在文中有兩點需要注意的,大家可以看下
    2018-04-04

最新評論

涡阳县| 湖北省| 三原县| 丽江市| 万山特区| 万山特区| 平利县| 洛宁县| 米泉市| 呼图壁县| 澜沧| 广西| 湖南省| 平邑县| 大理市| 东台市| 绥德县| 兴城市| 华阴市| 来宾市| 钦州市| 阳江市| 惠水县| 定陶县| 南阳市| 左贡县| 合江县| 芒康县| 会同县| 津市市| 资阳市| 五寨县| 阿坝县| 金门县| 福建省| 内黄县| 民勤县| 江门市| 昔阳县| 略阳县| 玛多县|