对集合成员的操做每每能够经过并行来提升效率,.NET Parallel类提供了简单的方法来帮助咱们实现这种并行,好比Paralle.For/ForEach/Invoke方法。函数
其中,For/ForEach方法提供了重载,容许咱们提供3个delegate,来实现对thread行为的控制。oop
函数声明以下:spa
public static ParallelLoopResult ForEach<TSource, TLocal>(IEnumerable<TSource> source, it
Func<TLocal> localInit, io
Func<TSource, ParallelLoopState, long, TLocal, TLocal> body, thread
Action<TLocal> localFinally); 效率
public static ParallelLoopResult ForEach<TSource, TLocal>(IEnumerable<TSource> source, 并行
Func<TLocal> localInit, 方法
Func<TSource, ParallelLoopState, TLocal, TLocal> body, im
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.