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

时间:2018-01-29 08:24:02

标签: vb.net dictionary text-files streamreader

我正在为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

1 个答案:

答案 0 :(得分:0)

我找到了一个更简单的解决方案,在一个函数中运行代码,然后将整个文本文件加载到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