最初,我使用foreach来完成我的任务。 但是,我想提高任务的效率。 所以,我想使用Parallel.ForEach来完成我的任务。
但是,错误“未将对象引用设置为实例”。发生了。
这是我的代码:
System.Threading.Tasks.Parallel.ForEach(items, item =>
{
System.Threading.Tasks.Parallel.ForEach(item.a, amount =>
{
WriteToCsv(file, amount.columna, count);
count++;
});
});
如果我使用foreach(项目中的var项目)和foreach(项目中的金额),代码可以正常工作。
我是否错过了Parallel.ForEach方法的内容?
答案 0 :(得分:8)
为什么要并行执行此操作?您正在将值附加到文件,这是一个串行(即非并行)进程。
如果您只是使用常规foreach
,那么您可以。
答案 1 :(得分:0)
你不应该嵌套多个Parallel Foreach循环,内部循环基本上是从外部并行循环中窃取资源,这在提高性能方面做得更好。
只有一个线程可以同时写入一个文件,因此大概在WriteToCsv()
内使用的任何函数都会在写入数据之前将所有内容重新编写回一个线程。
加快这一步的一种方法是在Parallel循环中构造要附加到CSV文件中的文本,然后使用单个写操作将其添加到其中:
var sb = new StringBuilder("");
System.Threading.Tasks.Parallel.ForEach(items, item =>
{
foreach( var amount in item.a )
{
sb.append( GetCsvText(file, amount.columna, count) );
count++;
};
});
WriteToCsv( sb.ToString() );
显然你无法控制订单文本将被放入CSV文件,因为它只是这段代码中线程之间的竞争,我认为这是好的,尽管你的示例代码也是如此。
N.B:在循环中构造字符串时,使用StringBuilder对于内存性能非常重要
HTH