方法一             
    IEnumerable<DataGridViewRow> dgvRows = this.dtCoordDataView.Rows.OfType<DataGridViewRow>();
                System.Threading.Tasks.Parallel.ForEach(dgvRows, dataRow =>
                {
                    string pointName = dataRow.Cells[this.PesNumColCount - 1].Value.ToString();
                    if (pointName.Length >= 2)
                    {
                        string pesName = pointName.Substring(pesNumStartSel, 2);
                        if (PesCodeNotNull(pesName))
                        {
                            DataTable dt = accDb.Table("select * from " + pesName + hz);
                           // DataTable dt = Wendao.WdSystem.Databases.Access.AccessDbEd.Table("select * from " + pesName + hz, oleConn);
                            bool notNull = false;
                            foreach (DataRow dtRow in dt.Rows)
                            {
                                string tPtName = dtRow[pointFieldName].ToString();
                                if (tPtName.Trim().ToUpper() == pointName.Trim().ToUpper())
                                {
                                    notNull = true;
                                    break;
                                }
                            }
                            if (!notNull)
                            {
                                pointNames.Add(pointName);
                            }
                        }
                    }
                });方法二
 foreach (DataGridViewRow dataRow1 in this.dtCoordDataView.Rows)
                {
                    string pointName = dataRow1.Cells[this.PesNumColCount - 1].Value.ToString();
                    if (pointName.Length >= 2)
                    {
                        string pesName = pointName.Substring(pesNumStartSel, 2);
                        if (PesCodeNotNull(pesName))
                        {
                            DataTable dt = accDb.Table("select * from " + pesName + hz);
                           // DataTable dt = Wendao.WdSystem.Databases.Access.AccessDbEd.Table("select * from " + pesName + hz, oleConn);
                            bool notNull = false;
                            foreach (DataRow dtRow in dt.Rows)
                            {                                
                                string tPtName = dtRow[pointFieldName].ToString();
                                if (tPtName.Trim().ToUpper() == pointName.Trim().ToUpper())
                                {
                                    notNull = true;
                                    break;
                                }
                            }
                            if (!notNull)
                            {
                                pointNames.Add(pointName);
                            }
                        }
                    }方法一用了PLINQ的Parallel.ForEach方法,方法二用了一般的foreach 
按理说方法一应该比方法二快,但是我运行下来方法一却比方法二慢了2秒多。请问是什么原因造成的啊?

解决方案 »

  1.   

    数据量越大,foreach比ForEach就越快
      

  2.   

    this.dtCoordDataView.Rows.OfType<DataGridViewRow>().AsParallel()....
      

  3.   

    并行循环有各种额外开销(比如同步开销,线程调度开销,委托调用开销),当这些开销“抵消”了并行执行带来的好处还有剩,就会导致比串行还慢。对于有些循环体执行时间很短的循环来说,仅仅是委托调用开销这一点就足以让并行循环比串行慢了。Parallel也提供了一些重载方法来减少委托的调用次数。(还有,Paralle.ForEach的同步开销可能比Parallel.For大一点,不确定。)另外还有一些和并行循环本身无关的原因。比如循环体的主要操作是调用一些外部代码,而这些外部代码“碰巧”作了简单的同步处理(比如内部获取了互斥锁),同一时间只能有一条线程访问。这样并行循环其实没什么用,只是白白增加了额外开销。具体到你的代码你自己分析一下吧。