调试Parallel.For循环中的失控线程

时间:2013-10-11 16:26:18

标签: c# multithreading task-parallel-library

我在.Net 4.5下运行以下代码

Parallel.For(0, fileArray.Length, i =>
            {
                DataRow dataRow = table.NewRow();
                var dr = GetDataRow(fileArray[i], dataRow, parameters);
                if (dr["MyVariable"].ToString() != "0")
                {
                    try
                    {
                        table.Rows.Add(dr);
                    }
                    catch (Exception exception)
                    {
                        ConfigLogger.Instance.LogError(exception);
                    }
                }
            }
        );

看似随意的这个循环将最大化机器上的处理器并停止在循环上不再进展。这是处理11k文件,我无法使用较小的文件集重复它。有没有人对如何调试这个有任何想法,并找出导致这种情况的原因?我无法在我的机器上复制它,我的机器和生产之间的差异如下

生产Win 7 64位,。Net 4.5

开发Win 8 64位,.Net 4.5.1

有没有办法在parallel.for循环的每个实例上放置超时异常?

1 个答案:

答案 0 :(得分:3)

如评论中所述,您需要使用线程本地数据表,Parallel已内置支持。此外,没有理由使用Parallel.ForForEach更适合这种情况。

Parallel.ForEach(fileArray,
                 () => 
                    {
                        lock(table)
                        {   
                            //Create a temp table per thread that has the same schema as the main table
                            return table.Clone(); 
                        }
                    },
                 (file, loopState, localTable) =>
                    {
                        DataRow dataRow = localTable.NewRow();
                        var dr = GetDataRow(file, dataRow, parameters);
                        if (dr["MyVariable"].ToString() != "0")
                        {
                            try
                            {
                                localTable.Rows.Add(dr);
                            }
                            catch (Exception exception)
                            {
                                ConfigLogger.Instance.LogError(exception);
                            }
                        }
                        return localTable;
                    },
                (localTable) =>
                {
                    lock (table)
                    {
                        //Merge in the thread local table to the master table
                        table.Merge(localTable); 
                    }
                });