Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Parallel.ForEach读取csv文件头的列?_C# - Fatal编程技术网

C# 如何使用Parallel.ForEach读取csv文件头的列?

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;

我必须读取一个巨大的csv文件,并希望使用Parallel.ForEach使读取速度更快。但是当我调试它时,列的标识就出了问题。有没有正确的方法

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时,瓶颈将是读取文件,而不是处理它。