[003][Concurrency in C# CookBook]Parallel.For, Parallel.Foreach基本範例

  • 16709
  • 0
  • 2016-10-27

摘要:[Concurrency]Parallel.For, Parallel.Foreach基本範例

Parallel的使用時機,都是在仰賴大量cpu計算的時候,才會用上,這邊參考msdn的範例,並適當的修改,作為以後自己參考

範例:


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Diagnostics;

namespace ConcurrencyConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            long totalSize = 0;            
            string strDirPath = "D:\\Projects";


          
            if (!Directory.Exists(strDirPath))
            {
                Console.WriteLine("The directory does not exist.");
                return;
            }

            String[] files = Directory.GetFiles(strDirPath,"*.*", SearchOption.AllDirectories);
            ConcurrentQueue queueFor = new ConcurrentQueue();
            ConcurrentQueue queueForEach = new ConcurrentQueue();
            //如果想評估平行處理是否有跑比較快,花比較短時間就執行完畢的話,msdn的範例是利用StopWatch類別喔
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            //Parallel.For範例:
            //index從0開始跑, 一直跑到 "files.Length -1"
            Parallel.For(0, files.Length,
                         index =>
                         {
                             //★★Parallel裡面若是想要下debug中斷點,逐步執行F10是無效的喔,需直接設定某一行為中斷點,然後直接按F5讓程式跳到那一行
                             //★★然後暫停住
                             FileInfo fi = new FileInfo(files[index]);
                             long size = fi.Length;
                             //如果平行處理回圈中,有每個回圈都需要共用的變數,這邊共用的變數是totalSize,記得利用Interlocked類別,以atomic execution的方式去修改此變數
                             Interlocked.Add(ref totalSize, size);
                             //如果平行處理回圈中,有每個回圈都存取的資料結構(如List),記得改用System.Collections.Concurrent下面的資料結構
                             //在平行處理的情況下才會穩定不當機(thread safe)                             
                             queueFor.Enqueue(fi.FullName);
                         });
            stopwatch.Stop();
            Console.WriteLine("Parallel.For:");
            Console.WriteLine("Directory '{0}':", strDirPath);
            Console.WriteLine("Executing Time(Milli second) '{0}':", stopwatch.ElapsedMilliseconds);
            Console.WriteLine("{0:N0} files, {1:N0} bytes", files.Length, totalSize);
            Console.WriteLine("file count in queue:" + queueFor.Count());
            Console.WriteLine();
            totalSize = 0;
            
           
            stopwatch.Start();
            //Parallel.ForEach範例:
            //從files之中,每個currentFile去平行執行
            Parallel.ForEach(files, currentFile =>
            {
                
                FileInfo fi = new FileInfo(currentFile);
                long size = fi.Length;
                //如果平行處理回圈中,有每個回圈都需要共用的變數,這邊共用的變數是totalSize,記得利用Interlocked類別,以atomic execution的方式去修改此變數
                Interlocked.Add(ref totalSize, size);
                //如果平行處理回圈中,有每個回圈都存取的資料結構(如List),記得改用System.Collections.Concurrent下面的資料結構
                //在平行處理的情況下才會穩定不當機(thread safe)                             
                queueForEach.Enqueue(fi.FullName);
            });
            stopwatch.Stop();
            Console.WriteLine("Parallel.ForEach:");
            Console.WriteLine("Directory '{0}':", strDirPath);
            Console.WriteLine("Executing Time(Milli second) '{0}':", stopwatch.ElapsedMilliseconds);
            Console.WriteLine("{0:N0} files, {1:N0} bytes", files.Length, totalSize);
            Console.WriteLine("file count in queue:" + queueFor.Count());
            Console.WriteLine("Press any key to continue");
            Console.ReadKey();

        }
        
    }
}

 

以上內容參考msdn:

如何:撰寫簡單的 Parallel.ForEach 迴圈

https://msdn.microsoft.com/zh-tw/library/dd460720(v=vs.110).aspx

如何:撰寫簡單的 Parallel.For 迴圈

https://msdn.microsoft.com/zh-tw/library/dd460713(v=vs.110).aspx

平行運算 (一):Parallel.For、Parallel.Foreach 用法及技巧

http://www.dotblogs.com.tw/asdtey/archive/2010/05/08/parallelforforeach.aspx