一. 并发(Concurrent)和并行(parallel)
看过这样一个例子:
你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。
你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。
你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。
并发的关键是你有处理多个任务的能力,不一定要同时。
并行的关键是你有同时处理多个任务的能力。
二.Parallel.ForEach数据并行
数据并行指的是对源集合或数组的元素同时(即,并行)执行相同操作的场景。 在数据并行操作中,对源集合进行分区,以便多个线程能够同时在不同的网段上操作。
Parallel.ForEach 循环的工作原理类似 Parallel.For 循环。 该循环对源集合进行分区,并根据系统环境在多个线程上安排工作。 系统上的处理器越多,并行方法的运行速度就越快。 对于一些源集合,有序循环可能会更快,具体视源大小以及该循环要执行的工作类型而定。
// Sequential version
foreach (var item in sourceCollection)
{
Process(item);
}
// Parallel equivalent
Parallel.ForEach(sourceCollection, item => Process(item));
三.ConcurrentBag类
ConcurentBag<T>
在一个线程中存储数据时,使用的是双向链表,ThreadLocalList
实现了一组对链表增删改查的方法。
ConcurrentBag线程安全
具体可以参考:C# ConcurrentBag的实现原理 - InCerry - 博客园 (cnblogs.com)
四,例子
//如果是需要写入处理很多东西后将结果写入到一个地方,可以使用
private static readonly int MaxParallelism = 10;
// Parallel equivalent
Parallel.ForEach(sourceCollection, item => Process(item));
var FileBag = new ConcurrentBag<string>();
Parallel.ForEach(sourceCollection, new ParallelOptions() { MaxDegreeOfParallelism = MaxParallelism }, source=>
{
//result=处理问题的程序后的结果
FileBag.Add(result);
});