为什么我的 Sub 一次只打印 1 行而不是 30 行?

Why is my Sub printing only 1 line at a time instead of 30?

我目前正在为 xmr-stak 编写 GUI (www.xmrgui.com) 从程序中获取输出时遇到一些问题,基本上想从输出文本文件中获取最后 30 行,如果它们不存在,则将它们附加到 RichTextBox 中。将文本文件存储在内存中不是一个大问题,因为它每 20 分钟左右就会被删除一次……至少我认为是这样。也许我的功能占用了太多内存或时间。

我唯一的要求是 Sub TimerOutput_tick 可以处理文件中最后 30 行文本中的每一行,并在每行上 运行 一个正则表达式,并且 RichTextBox 不会重复旧信息.

这是我的代码:

Private Function getlastlines(filename As String, numberOfLines As Integer) As Dictionary(Of Integer, String)
    Try
        Dim fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
        Dim reader As StreamReader = New StreamReader(fs)
        Dim everything As New Dictionary(Of Integer, String)
        Dim n As Integer = 1
        While reader.Peek > -1
            Dim line = reader.ReadLine()
            If everything.ContainsKey(n) Then
                everything(n) = line
                n += 1
            Else
                everything.Add(n, line)
                n += 1
            End If
        End While
        Dim results As New Dictionary(Of Integer, String)
        Dim z As Integer = 1
        If n - numberOfLines > 0 Then
            For x As Integer = n - numberOfLines To n - 1
                'MsgBox(everything.Count - numberOfLines)
                If results.ContainsKey(z) Then
                    results(z) = everything(x)
                    z += 1
                Else
                    results.Add(z, everything(x))
                    z += 1
                End If
            Next

        End If

        Return results
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try

End Function
' GRABS XMR-STAK OUTPUT FROM ReadLastLinesFromFile AND RUNS A REGEX ON THE HASHRATE TO PROVIDE VALUES TO THE CHART

这里是调用前一个函数的 Sub:

Private Sub timeroutput_Tick(sender As Object, e As EventArgs) Handles timeroutput.Tick
    'Try
    Dim lateststring = getlastlines(xmroutput, 30)
    Try
        If lateststring IsNot rtlateststring Then
            Dim kvp As KeyValuePair(Of Integer, String)
            For Each kvp In lateststring
                If lateststring.ContainsKey(kvp.Key) Then


                    Dim line = kvp.Value
                    RichTextBox1.AppendText(line & vbCrLf)


                    If line.Contains("Totals") Then ' Should be "Totals"
                        'Dim regex As Regex = New Regex("\d+?.\d+")
                        Dim regex As Regex = New Regex("\d{1,5}\.\d{1,1}") ' match a double
                        Dim ret = regex.Match(line).Value

                        If ret <> "" Then
                            Dim iSpan As TimeSpan = TimeSpan.FromSeconds(upseconds)
                            Label8.Text = "Uptime - Hours: " & iSpan.Hours & " Minutes: " & iSpan.Minutes & " Seconds: " & iSpan.Seconds & "               " & ret & " H/s"
                            NotifyIcon1.Text = "Uptime - Hours: " & iSpan.Hours & vbCrLf & " Minutes: " & iSpan.Minutes & vbCrLf & " Seconds: " & iSpan.Seconds & vbCrLf & ret & " H/s"
                        Else
                            Dim iSpan As TimeSpan = TimeSpan.FromSeconds(upseconds)
                            NotifyIcon1.Text = "Uptime - Hours: " & iSpan.Hours & vbCrLf & " Minutes: " & iSpan.Minutes & vbCrLf & " Seconds: " & iSpan.Seconds & vbCrLf & "Initializing..."
                            Label8.Text = "Uptime - Hours: " & iSpan.Hours & " Minutes: " & iSpan.Minutes & " Seconds: " & iSpan.Seconds & "            Initializing..."
                            ret = "0.0"
                        End If
                        'Dim match As Match = regex.Match(lastline)
                        newhashrate = Convert.ToDouble(ret)
                    ElseIf line.Contains("NVIDIA") Then
                        Dim regexnv As Regex = New Regex("\d{1,5}\.\d{1,1}") ' match a double
                        Dim retnv = regexnv.Match(line).Value
                        newNVhashRate = Convert.ToDouble(retnv)
                        If firstNV = False Then
                            newser.Add(nvidiacard1)
                            nvidiacard1.Title = "NIVIDIA Hashrate(H/s)"
                            nvidiacard1.Values = nvidiavalues
                            nvidiavalues.add(0)
                            nvidiavalues.add(4)
                            nvidiavalues.add(2)
                            nvidiavalues.add(5)
                            firstNV = True
                        End If
                    ElseIf line.Contains("AMD") Then
                        Dim regexAMD As Regex = New Regex("\d{1,5}\.\d{1,1}") ' match a double
                        Dim retAMD = regexAMD.Match(line).Value
                        newAMDhashrate = Convert.ToDouble(retAMD)
                        If firstAMD = False Then
                            newser.Add(AMDCard1)
                            AMDCard1.Title = "AMD Hashrate(H/s)"
                            AMDCard1.Values = AMDValues
                            AMDValues.add(0)
                            AMDValues.add(4)
                            AMDValues.add(2)
                            AMDValues.add(5)
                            firstAMD = True
                        End If
                    End If
                    ' Now if a GPU exists, add a new lineseries for CPU
                    If firstAMD = True Or firstNV = True Then
                        If firstCPU = False Then
                            newser.Add(CPU1)
                            CPU1.Title = "CPU Hashrate(H/s)"
                            CPU1.Values = CPUValues
                            CPUValues.add(0)
                            CPUValues.add(4)
                            CPUValues.add(2)
                            CPUValues.add(5)
                            firstCPU = True
                        End If
                        newCPUhashrate = newhashrate - newNVhashRate - newAMDhashrate
                    End If
                    rtlateststring = lateststring
                End If
            Next
            RichTextBox1.SelectionStart = RichTextBox1.Text.Length
        End If
    Catch
    End Try
End Sub

我找到了一个更简单的解决方案,运行 一个函数中的代码,然后将整个文本文件加载到 richtextbox 中。从那里单独阅读最后十行要容易得多:

Private Sub timeroutput_Tick(sender As Object, e As EventArgs) Handles timeroutput.Tick
    Try
        'Dim lateststring = getlastlines(xmroutput, 30)
        ' START NEW TEST
        Dim fs = File.Open(xmroutput, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
        Dim reader As StreamReader = New StreamReader(fs)
        Dim wholefile = reader.ReadToEnd
        RichTextBox1.Text = wholefile
        RichTextBox1.SelectionStart = RichTextBox1.Text.Length
        For x As Integer = 1 To 10
            Dim line As String = RichTextBox1.Lines(RichTextBox1.Lines.Length - x)
            If line.Contains("Totals") Then ' Should be "Totals"
                'Dim regex As Regex = New Regex("\d+?.\d+")
                Dim regex As Regex = New Regex("\d{1,5}\.\d{1,1}") ' match a double
                Dim ret = regex.Match(line).Value

                If ret <> "" Then
                    Dim iSpan As TimeSpan = TimeSpan.FromSeconds(upseconds)
                    Label8.Text = "Uptime - Hours: " & iSpan.Hours & " Minutes: " & iSpan.Minutes & " Seconds: " & iSpan.Seconds & "               " & ret & " H/s"
                    NotifyIcon1.Text = "Uptime - Hours: " & iSpan.Hours & vbCrLf & " Minutes: " & iSpan.Minutes & vbCrLf & " Seconds: " & iSpan.Seconds & vbCrLf & ret & " H/s"
                Else
                    Dim iSpan As TimeSpan = TimeSpan.FromSeconds(upseconds)
                    NotifyIcon1.Text = "Uptime - Hours: " & iSpan.Hours & vbCrLf & " Minutes: " & iSpan.Minutes & vbCrLf & " Seconds: " & iSpan.Seconds & vbCrLf & "Initializing..."
                    Label8.Text = "Uptime - Hours: " & iSpan.Hours & " Minutes: " & iSpan.Minutes & " Seconds: " & iSpan.Seconds & "            Initializing..."
                    ret = "0.0"
                End If
                'Dim match As Match = regex.Match(lastline)
                newhashrate = Convert.ToDouble(ret)
            ElseIf line.Contains("NVIDIA") Then
                Dim regexnv As Regex = New Regex("\d{1,5}\.\d{1,1}") ' match a double
                Dim retnv = regexnv.Match(line).Value
                newNVhashRate = Convert.ToDouble(retnv)
                If firstNV = False Then
                    newser.Add(nvidiacard1)
                    nvidiacard1.Title = "NIVIDIA Hashrate(H/s)"
                    nvidiacard1.Values = nvidiavalues
                    For Each z In Chartvalues
                        Chartvalues.remove(z)
                    Next
                    nvidiavalues.add(0)
                    firstNV = True
                End If
            ElseIf line.Contains("AMD") Then
                Dim regexAMD As Regex = New Regex("\d{1,5}\.\d{1,1}") ' match a double
                Dim retAMD = regexAMD.Match(line).Value
                newAMDhashrate = Convert.ToDouble(retAMD)
                If firstAMD = False Then
                    newser.Add(AMDCard1)
                    AMDCard1.Title = "AMD Hashrate(H/s)"
                    AMDCard1.Values = AMDValues
                    For Each z In Chartvalues
                        Chartvalues.remove(z)
                    Next
                    AMDValues.add(0)
                    firstAMD = True
                End If
            End If
            ' Now if a GPU exists, add a new lineseries for CPU
            If firstAMD = True Or firstNV = True Then
                If firstCPU = False Then
                    newser.Add(CPU1)
                    CPU1.Title = "CPU Hashrate(H/s)"
                    CPU1.Values = CPUValues
                    For Each z In Chartvalues
                        Chartvalues.remove(z)
                    Next
                    CPUValues.add(0)
                    Chartvalues.add(0)
                    firstCPU = True
                End If
                newCPUhashrate = newhashrate - newNVhashRate - newAMDhashrate
            End If
        Next
    Catch
    End Try
    ' END NEW TEST
End Sub