.Net使用Parallel.ForEach处理大型文件不保持顺序

时间:2017-05-22 20:33:16

标签: .net parallel-processing parallel.foreach

我正在编写一段vb.net代码,逐行处理一个大型文本文件,其中19列由Quote分隔,后跟逗号和另一个引号(即",")。我根据分隔符值(",")分割线。然后我查找每列(col)仍然包含的任何额外双引号并记录到db表(如果找到)。我能够处理它,但问题是订单没有得到维护。我需要写入数据库表,哪些行和列包含分隔的char(用于进一步处理)。似乎某种程度上循环无法捕捉到订单。

<***> ****例如****:如果输入文件包含10行和19个col,并且在row1的最后一列(第19列)和第10行的最后一个col上找到无效的分隔字符,则记录( WriteLogToDb(Path.GetFileName(FileAlign.Common.InputFileName),rownum,colnum ,,,,,,,,,,,,)发生如下:row1 - 打印正确。但是,而不是说第10行包含错误的列值,parallel.foreach循环表示第5行在第19位有错误的col。考虑到列数,该顺序似乎是正确的。

我在这里做错了什么?任何替代品?

示例文件 - &gt;

&#34; col1val&#34;&#34;&#34; col2val&#34;&#34;&#34;&#34;&#34;&#34; CCCCCC&#34; &#34;&#34; XXXXXX&#34;&#34;&#34; XXXX&#34;&#34;&#34; 12334&#34;&#34;&#34; 331&# 34;&#34;,35344535&#34;&#34;&#34; XXX&#34;&#34;&#34; WA&#34;&#34;&#34; 50000&#34; #&34;,&#34;&#34;&#34;&#34; 03/01/2000&#34;&#34;&#34;&#34;&#34;&# 34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34; Lin1Col19&#34; ROW2 - &GT; row3-&GT; - - 等等 row9 - &GT; &#34; col1val&#34;&#34;&#34; col2val&#34;&#34;&#34;&#34;&#34;&#34; AAAA&#34;&#34 ;,&#34; XXXXXX&#34;&#34;&#34; XXXX&#34;&#34;&#34; 4242&#34;&#34;&#34; 6464&#34;& #34;,533535353&#34;&#34;&#34; XXX&#34;&#34;&#34; PA&#34;&#34;&#34; 6446 enter code here& #34;&#34;&#34;&#34;&#34;&#34; 04/01/1967&#34;&#34;&#34;&#34;&#34; &#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34; Lin1Col19&# 34;

这是代码示例。

Public Sub ValidateExtraDoubleQuotes(FileName As String)
    Dim InputFile As String = FileName
    Dim rownum As Integer = 0
    Dim colnum As Integer = 0
    Dim SplittedValues() As String
    Dim delimiter As String = ""","""   '/*ie delimiter is ","*/
    Dim QT As String = """"   'escape single doublequote by adding another
    Dim ExtraQTFound As Boolean = False
    Dim QTRowCount As Long = 0
    Dim messagesLockRow As New Object
    Dim messagesLockCol As New Object

    Try

        Parallel.ForEach(File.ReadLines(InputFile), Sub(line As String)
                                                        Console.WriteLine(line)
                                                        SyncLock messagesLockRow
                                                            rownum += 1
                                                            '/*' remove first and last chars from each line for further processing(ie. extra double quotes) *
                                                            line = (line.Remove(0, 1)).Remove(line.Length - 2, 1)
                                                            SplittedValues = line.Split(New String() {delimiter}, StringSplitOptions.None)
                                                            SyncLock messagesLockCol
                                                                For Each Str As String In SplittedValues
                                                                    colnum += 1
                                                                    If Str.Contains(QT) Then
                                                                        ExtraQTFound = True
                                                                        WriteLogToDb(Path.GetFileName(FileAlign.Common.InputFileName), rownum, colnum, False, "Extra Double Quotes for-->" & Str)
                                                                    End If
                                                                Next
                                                            End SyncLock
                                                            colnum = 0
                                                            ExtraQTFound = False
                                                        End SyncLock
                                                    End Sub)
    Catch ex As Exception
        Console.Write(String.Concat("Exception!!", ex.Message.ToString()))
    End Try

End Sub

1 个答案:

答案 0 :(得分:0)

使用Parallel.ForEach,您可以通过将工作分配给不同的线程并将其输出在执行完成后合并,命令您的代码一次处理多行。这样做不能保证订单。只有当顺序无关紧要或者您有自己的方式在执行后重新排序数据时,才应该使用并行性。

至于替代品。您可以执行诸如将每行读取到数组之类的操作然后使用parallel.ForEach在将数据保存在可维护顺序的对象中之后执行处理工作。此时如果出现错误,那么您可以将错误消息传递给对象以及数组索引,并在所有处理发生后根据数组索引顺序写入数据库:此链接将向您显示如何工作with parallel.foreach loops http://www.blackwasp.co.uk/ParallelForEachIndex.aspx

中的数组索引