Parallel 類提供對并行循環和區域的支持。
許多個人計算機和工作站都有兩個或四個內核(即 CPU),使多個線程能夠同時執行。 在不久的將來,計算機預期會有更多的內核。 為了利用當今和未來的硬件,您可以對代碼進行并行化,以將工作分攤在多個處理器上。 過去,并行化需要線程和鎖的低級操作。 Visual Studio 2010 和 .NET Framework 4 提供了新的運行時、新的類庫類型以及新的診斷工具,從而增強了對并行編程的支持。 這些功能簡化了并行開發,使您能夠通過固有方法編寫高效、細化且可伸縮的并行代碼,而不必直接處理線程或線程池。 下圖從較高層面上概述了 .NET Framework 4 中的并行編程體系結構。
上面是MSDN對于并行任務的解釋,簡而言之就是同時執行多個任務,帶來效率上的提高,但是同時帶來CPU占用;
1.簡單Parallel.For/Parallel.ForEach循環
using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; namespace Consoleapplication17
{ class PRogram
{ static void Main(string[] args)
{ try { NormalFor();
ParallelFor();
}
catch (Exception ex) { Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));
}
finally { Console.ReadLine();
}
}
static int _forCount = 100;
static void NormalFor()
{ Stopwatch _watch = new Stopwatch(); _watch.Start();
for (int i = 0; i < _forCount; i++)
{ DoSomeWork(i);
}
_watch.Stop();
Console.WriteLine(string.Format("Normal For Cost Time:{0}", _watch.ElapsedMilliseconds));
}
static void ParallelFor()
{ Stopwatch _watch = new Stopwatch(); _watch.Start();
//寫法一 Parallel.For(0, _forCount, i =>
{ DoSomeWork(i);
});
_watch.Stop();
Console.WriteLine(string.Format("Parallel For Cost Time:{0}", _watch.ElapsedMilliseconds));
/* Parallel.For(0, _forCount, DoSomeWork);//寫法二 Parallel.For(0, _forCount, (int i) => { DoSomeWork(i); });//寫法三 */ }
static void DoSomeWork(int i)
{ if (i < 0) throw new ArgumentException("i");
Thread.Sleep(100);
}
}
}
代碼效果

using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication17 { class Program { static void Main(string[] args)
{ try { BreakParallelFor();
}
catch (Exception ex) { Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));
}
finally { Console.ReadLine();
}
}
static int _forCount = 100;
static void BreakParallelFor()
{ Parallel.For(0, _forCount, (i, status) =>
{ if (i == 22) { Console.WriteLine("Parallel For Break...."); status.Break();
}
Console.WriteLine(string.Format("output :{0}", i));
Thread.Sleep(100);
});
}
}
}
代碼效果

看看MSDN關于此的解釋:
在 ParallelFor() 或 [Overload:System.Threading.Tasks.Parallel.Parallel.ForEach`1] 循環中,不能使用與順序循環中相同的 break 或 Exit 語句,這是因為這些語言構造對于循環是有效的,而并行“循環”實際上是方法,不是循環。 相反,可以使用 Stop 或 Break 方法。 Parallel.For的一些重載接受 Action<int, ParallelLoopState>(在 Visual Basic 中為 Action(Of Integer, ParallelLoopState))作為輸入參數。 ParallelLoopState 對象由運行時在后臺創建,您可以在 lambda 表達式中為它指定您喜歡的任何名稱。
在調用 Stop 或 Break 后,循環中的其他線程可能會繼續運行一段時間(這不受應用程序開發人員的控制),理解這一點很重要。 可以使用 ParallelLoopState.IsStopped 屬性檢查是否已在另一個線程上停止該循環。
理解黃色標注地方很重要;
3.具有線程局部變量的 Parallel.ForEach Parallel.For 循環
using System;using System.Linq;using System.Threading;using System.Threading.Tasks;namespace ConsoleApplication17{ class Program { static void Main(string[] args) { try { //例子參考自MSDN:http://msdn.microsoft.com/zh-cn/library/dd460703%28v=vs.100%29.aspx int[] _nums = Enumerable.Range(0, 10).ToArray(); long _fortotal = 0, _foreahtotal = 0; Parallel.For<long>(0, _nums.Length, () => 0,//每次遍歷開始時候初始化變量 類似于 int _subSum=0; (i, loopStatus, eachLoopTotal) =>//i:循環的索引;loopstatus:并行遍歷狀態;eachLoopTotal:每次遍歷累加小計值 { eachLoopTotal += _nums[i]; return eachLoopTotal; }, (eachLoopTotal) =>//遍歷結束時候,將上面每次累加小計數值傳遞過來,進行總的累加 { Interlocked.Add(ref _fortotal, eachLoopTotal); }); /* localInit 類型:System.Func<TLocal> 用于返回每個線程的本地數據的初始狀態的函數委托。 body 類型:System.Func<Int64, ParallelLoopState, TLocal, TLocal> 將為每個迭代調用一次的委托。 localFinally 類型:System.Action<TLocal> 用于對每個線程的本地狀態執行一個最終操作的委托。 */ Parallel.ForEach<int, long>(_nums, () => 0, (i, loopStatus, eachLoopTotal) => { eachLoopTotal += _nums[i]; return eachLoopTotal; }, (eachLoopTotal) => { Interlocked.Add(ref _foreahtotal, eachLoopTotal); }); Console.WriteLine("The Parallel.For is {0}", _fortotal); Console.WriteLine("The Parallel.ForEach is {0}", _foreahtotal); } catch (Exception ex) { Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim())); } finally { Console.ReadLine(); } } }}
代碼效果

4.取消 Parallel.For/ForEach Loop
using System; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication17 { class Program { static void Main(string[] args)
{ try { /* CancellationToken 獲取或設置與此 ParallelOptions 實例關聯的 CancellationToken。 MaxDegreeOfParallelism 獲取或設置此 ParallelOptions 實例所允許的最大并行度。 TaskScheduler 獲取或設置與此 ParallelOptions 實例關聯的 TaskScheduler。 將此屬性設置為 null,以指示應使用當前計劃程序。 MaxDegreeOfParallelism MaxDegreeOfParallelism設置為2,表示最多可以有2個并行量(可以理解成并行線程數目),如果設置為為 -1,表示對于應該使用的并行量沒有上限設置。如果將其設置為1,則效果和單線程一樣. */ CancellationTokenSource _cancel = new CancellationTokenSource(); ParallelOptions _po = new ParallelOptions(); _po.CancellationToken = _cancel.Token;
_po.MaxDegreeOfParallelism = Environment.ProcessorCount;
Parallel.For(0, 100, _po, i =>
{ if (i == 22) _cancel.Cancel();
Console.WriteLine(string.Format("output {0}", i));
});
}
catch (OperationCanceledException e)
{ Console.WriteLine(e.Message);
}
catch (Exception ex) { Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));
}
finally { Console.ReadLine();
}
}
}
}
代碼效果

新聞熱點
疑難解答