對集合成員的操作往往可以通過并行來提高效率,.NET Parallel類提供了簡單的方法來幫助我們實現這種并行,比如Paralle.For/ForEach/Invoke方法。
其中,For/ForEach方法提供了重載,允許我們提供3個delegate,來實現對thread行為的控制。
函數聲明如下:
public static ParallelLooPResult ForEach<TSource, TLocal>(IEnumerable<TSource> source,
Func<TLocal> localInit,
Func<TSource, ParallelLoopState, long, TLocal, TLocal> body,
Action<TLocal> localFinally);
public static ParallelLoopResult ForEach<TSource, TLocal>(IEnumerable<TSource> source,
Func<TLocal> localInit,
Func<TSource, ParallelLoopState, TLocal, TLocal> body,
Action<TLocal> localFinally);
上面2個聲明的差別在于一個long型輸入參數,這個參數是元素在集合中的index,由CLR傳遞給body函數。
需要注意的是,localInit只是在每個task/thread開始參與到對集合元素的處理時執行一次,而不是針對每個集合元素都執行一次,類似的,localFinally只有在task/thread完成所有分配給它的任務之后,才被執行一次。
CLR會為每個Thread/Task維護一個thread-local storage,可以理解為thread/task在整個執行過程中的狀態。
當一個thread/task參與到執行中時,localInit中返回的TLocal類型值會被作為這個狀態的初始值,隨著body的執行,這個狀態值會被改變,而body的返回類型也是TLocal,意味著每一次body執行結束,會把最新的TLocal值返回給CLR,而CLR會把這個值設置到thread/task的thread-local storage上去,從而實現thread/task狀態的更新。
最后,localFinally可以返回這個狀態值,作為thread/task完成它所負責的所有處理任務后的最終結果。
參考:(http://msdn.microsoft.com/en-us/library/dd783359%28v=vs.110%29.aspx)
CLR via C# 4th Edition Ch.27 Parallel's Static For, ForEach, and InvokeMethods.
新聞熱點
疑難解答