Xan*_*rUu 4 c# parallel-processing datatable
我试图在并行中向DataTable添加一些信息,但是如果循环是长时间它会冻结或者只需要花费很多时间,那么通常用于循环,这是我的Parallel.For循环代码:
Parallel.For(1, linii.Length, index =>
{
DataRow drRow = dtResult.NewRow();
alResult = CSVParser(linii[index], txtDelimiter, txtQualifier);
for (int i = 0; i < alResult.Count; i++)
{
drRow[i] = alResult[i];
}
dtResult.Rows.Add(drRow);
}
);
Run Code Online (Sandbox Code Playgroud)
怎么了?这个Parallel.For循环比正常循环花费的时间多得多,出了什么问题?
谢谢!
你不能改变DataTable2个不同的线程; 它会出错.DataTable让没有尝试是线程安全的.所以:不要那样做.从一个线程做到这一点.很可能你受到IO的限制,所以你应该在一个线程上作为流来做.看起来你正在处理文本数据.你似乎有一条string[]换线,或许File.ReadAllLines()?嗯,这里非常糟糕:
你应该做的是使用像代码项目中的CsvReader,但即使你想一次只使用一行,使用StreamReader:
using(var file = File.OpenText(path)) {
string line;
while((line = file.ReadLine()) != null) {
// process this line
alResult = CSVParser(line, txtDelimiter, txtQualifier);
for (int i = 0; i < alResult.Count; i++)
{
drRow[i] = alResult[i];
}
dtResult.Rows.Add(drRow);
}
}
Run Code Online (Sandbox Code Playgroud)
这会不会是用更快Parallel,所以我还没有尝试这样做.IO是你的瓶颈.锁定是一种选择,但它不会对你有大的帮助.
作为一个无关的,我注意到它alResult没有在循环中声明.这意味着在您的原始代码中alResult是一个捕获的变量,它在所有循环迭代之间共享- 这意味着您已经可怕地覆盖每一行.
编辑:为什么Parallel与从文件中读取1,000,000行无关的说明:
方法1:用于ReadAllLines加载线,然后Parallel用来处理它们; 这花费了物理文件IO的[固定时间],然后我们并行化.CPU工作很少,我们基本上花了[固定时间].但是,我们添加了大量的线程开销和内存开销,甚至在加载所有文件之前我们都无法启动.
方法2:使用流API; 逐行读取每一行 - 处理每一行并添加它.这里的成本基本上是:[固定时间]用于加载文件的实际IO带宽.但; 我们现在有没有线程的开销,不同步冲突,没有巨大的内存来分配,我们开始填写表格的时候了.
方法3:如果你真的想要,第三种方法将是一个读/写队列,一个专用的线程处理文件IO并将这些行排队,另一个方法就是这样做DataTable.坦率地说,它是更多移动部件,第二个线程将花费95%的时间等待来自文件的数据; 坚持方法2!
| 归档时间: |
|
| 查看次数: |
1153 次 |
| 最近记录: |