摘要:[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