c# – Parallel.For循环冻结
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – Parallel.For循环冻结,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2045字,纯文字阅读大概需要3分钟。
内容图文
我试图在并行中向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);
}
);
怎么了?这个Parallel.For循环比正常循环花费的时间多得多,出了什么问题?
谢谢!
解决方法:
你不能从2个不同的线程变异DataTable;它会出错. DataTable不会尝试线程安全.所以:不要那样做.从一个线程做到这一点.很可能你受到IO的限制,所以你应该在一个线程上作为流来做.看起来你正在处理文本数据.你似乎有一个字符串[]为行,也许File.ReadAllLines()?嗯,这里非常糟糕:
>它强制将所有内容加载到内存中
>你必须等待所有内容加载到内存中
> CSV是一种多行格式;不保证1行== 1行
你应该做的是使用像代码项目中的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);
}
}
使用Parallel并不会更快,所以我没有尝试这样做. IO是你的瓶颈.锁定是一种选择,但它不会对你有大的帮助.
作为一个无关的,我注意到alResult没有在循环中声明.这意味着在您的原始代码中,alResult是一个捕获的变量,它在所有循环迭代之间共享 – 这意味着您已经可怕地覆盖每一行.
编辑:插图为什么Parallel与从文件中读取1,000,000行无关:
方法1:使用ReadAllLines加载行,然后使用Parallel处理它们;这花费了物理文件IO的[固定时间],然后我们并行化. CPU工作很少,我们基本上花了[固定时间].但是,我们添加了大量的线程开销和内存开销,甚至在加载所有文件之前我们都无法启动.
方法2:使用流API;逐行读取每一行 – 处理每一行并添加它.这里的成本基本上是:[固定时间]用于加载文件的实际IO带宽.但;我们现在没有线程开销,没有同步冲突,没有大量内存要分配,我们立即开始填充表.
方法3:如果你真的想要,第三种方法是读/写队列,一个专用的线程处理文件IO和队列,第二个方法是DataTable.坦率地说,它是更多移动部件,第二个线程将花费95%的时间等待来自文件的数据;坚持方法2!
内容总结
以上是互联网集市为您收集整理的c# – Parallel.For循环冻结全部内容,希望文章能够帮你解决c# – Parallel.For循环冻结所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。