C# 如何使用Parallel.ForEach读取csv文件头的列?
我必须读取一个巨大的csv文件,并希望使用Parallel.ForEach使读取速度更快。但是当我调试它时,列的标识就出了问题。有没有正确的方法C# 如何使用Parallel.ForEach读取csv文件头的列?,c#,C#,我必须读取一个巨大的csv文件,并希望使用Parallel.ForEach使读取速度更快。但是当我调试它时,列的标识就出了问题。有没有正确的方法 StreamReader _headerReader = new StreamReader(folder); string[] header = _headerReader.ReadLine().Split(','); int headerColumn = 0; int firstColumn = 0; int secondColumn = 0;
StreamReader _headerReader = new StreamReader(folder);
string[] header = _headerReader.ReadLine().Split(',');
int headerColumn = 0;
int firstColumn = 0;
int secondColumn = 0;
int thirdColumn = 0;
// And etc...
Parallel.ForEach(header, content =>
{
switch(header[headerColumn])
{
case"First"
firstColumn = headerColumn;
break;
case"Second"
SecondColumn = headerColumn;
break;
case"Thrid"
thirdColumn = headerColumn;
break;
// And etc...
}
headerColumn++;
}
我想在每个列变量中放置每个列的编号,但编号的顺序从来都不正确。您要求
并行
在多个线程中处理字符串数组,然后忽略内容
参数以将您自己的索引滚动到该数组,不控制何时更改循环变量
假设有两个线程运行代码,并且线程不同步。让我们看看会发生什么
Thread1 Thread2 headerColumn
1 switch (header[headerColumn]) 0
2 case "first": 0
3 firstColumn = headerColumn; 0
4 switch (header[headerColumn]) 0
5 break; 0
6 case "first": 0
7 headerColumn++; 1
8 firstColumn = headerColumn; 1
9 break; 1
10 headerColumn++; 2
在第7行,Thread1在Thread2测试值之后,但在将值分配给firstColumn
之前,递增headerColumn
。因此,两个线程都为firstColumn
分配一个值,两个线程都不会修改secondColumn
,以此类推
这是一个巨大的过度简化。实际上,多个线程可以在不同的CPU核上同时执行。如果增量操作是以一系列指令(例如,load;increment;store
)而不是原子增量或联锁增量来实现的,那么如果增量期间多个线程发生冲突,则最终可能会导致headerColumn
小于预期值
相反,您应该在并行部分之外生成索引,并将其与头名称一起传入。大概是这样的:
headers.Select((name, index) => new { name, index })
.AsParallel()
.ForAll
(
header =>
{
switch (header.name)
{
case "First":
firstColumn = header.index;
break;
case "Second":
secondColumn = header.index;
break;
}
}
);
这就是说,除非你在数百列上工作,否则你不会看到太多的速度提高。。。而针对数百列编写此代码将是非常可怕的
有很多好的CSV阅读器。例如,它在CSV和类之间有自动映射,所以您不必自己处理标题,您只需读取一系列对象
重新发明轮子可能很有趣,你当然可以学到很多东西,但如果你不把时间浪费在其他人已经提供的解决方案上,那就有很多话要说。我们在这里谈论的有多大?@HansPassant阅读代码。他按顺序阅读,并行处理。他不明白平行就是一切。如果你能提供一个。一定要解释代码试图做什么,以及当前需要多长时间。你确定并行化会提高性能(明显地)?通常,当涉及I/O时,瓶颈将是读取文件,而不是处理它。