并行。失败(C#)

我写了一些代码:

class Program { public const int count = 3000; static List list = new List(); static void DoWork(int i) { list.Add(i); } static void Main(string[] args) { while (true) { Stopwatch s = new Stopwatch(); s.Start(); Parallel.For(0, count + 1, DoWork); s.Stop(); Console.WriteLine("\n Elapsed: " + s.Elapsed.ToString()); Console.WriteLine("Expected: {0}", count + 1); Console.WriteLine("count: {0}", list.Count); Console.ReadKey(); list = new List(); } } } 

但结果不是预期的(

并非所有循环都在Console.WriteLine调用之前完成

使用Parallel.For有什么问题?

你正在遇到所谓的竞争条件 。 由于.Net中的List集合不是线程安全的,因此Add()之类的操作不是primefaces的。 基本上,在一个线程上调用Add()可以在完成之前销毁另一个线程的Add()。 您需要为代码提供线程安全的并发集合。

试试这个:

 using System.Threading.Tasks; class Program { public const int count = 3000; static ConcurrentBag bag = new ConcurrentBag(); static void DoWork(int i) { bag.Add(i); } static void Main(string[] args) { while (true) { Stopwatch s = new Stopwatch(); s.Start(); Parallel.For(0, count + 1, DoWork); s.Stop(); Console.WriteLine("\n Elapsed: " + s.Elapsed.ToString()); Console.WriteLine("Expected: {0}", count + 1); Console.WriteLine("count: {0}", bag.Count); Console.ReadKey(); bag = new ConcurrentBag(); } } } 

ConcurrentBag是最接近线程安全列表的东西。 请记住,因为我们正在处理未知的调度,所以整数将不按顺序排列。

List<>类不是线程保存。 你不能在并行循环中修改它(没有问题)。 使用System.Collections.Concurrent命名空间的集合

List不是线程安全的类。 您应该使用其中一个Concurrent集合,或者实现您自己的同步。

有关Parallel.For详细信息,请参阅此答案