废话很少说,上代码:编程
using System; using System.Collections.Generic; using System.Threading.Tasks; namespace ParallelTest { class Program { static void Main(string[] args) { List<Product> products = new List<Product>(); Parallel.For(0, 1000000, (i) => { Product product = new Product(); product.Name = "name" + i; product.Category = "Category" + i; product.SellPrice = i; products.Add(product); }); Console.WriteLine(products.Count); Console.ReadLine(); } } class Product { public string Name { get; set; } public string Category { get; set; } public int SellPrice { get; set; } } }
猜一下,运行结果是多少,是999999?抱歉不是的,结果!= 999999。数组
Net 4.0引入了System.Threading.Tasks,简化了咱们进行异步编程的方式,而不用直接与线程和线程池打交道,但这也引入了线程安全问题。安全
System.Threading.Tasks中的类型被称为任务并行库(TPL)。TPL使用CLR线程池(说明使用TPL建立的线程都是后台线程)自动将应用程序的工做动态分配到可用的CPU中。多线程
其中Parallel是指数据并行,其提供的Parallel.For()或Parallel.ForEach()方法,能够以并行方式对数组或集合中的数据进行迭代。异步
那之因此出现这个结果,很显然了,是多线程操做集合致使的线程安全问题。异步编程
总之,多线程操做集合时必定要注意线程安全的问题,无论是经过Thread、ThreadPool、Task、Parallel仍是PLINQ。spa
解决方案很简单:线程
对于这个问题,我知道其存在潜在的线程安全问题,可是不肯定其致使的结果如何?当我截图处处询问无果时,才想到本身动手写demo去验证问题。这也是我写这篇文章的初衷:提醒本身,遇到问题,不要凭空猜想,要有动手验证的决心。code