StreamReader小型与大型文件读取时间不排队

时间:2016-01-25 20:14:38

标签: vb.net multithreading performance io streamreader

请参阅以下代码。这基本上只是我的一个实验,所以我可以在Visual Basic中解决各种问题,即如何使用后台工作程序,读取文件等。

我有一个100,000行的小文件,以及1,000,000行的大文件。

文件结构为“数据A |数据A-1”,新行,“数据A |数据A-2”等,一直向下。

我正在做的是让用户选择文件,然后将其填充到两个列表框中,以便能够看到数据正确读取。

以下代码在我的机器上大约需要22秒来读取小文件的完成情况,但是大文件需要8分半钟才能完成。对于较大的文件,我预计在3:30到4分钟之间的时间,基于行数。这个额外的时间来自哪里?我有什么办法可以摆脱它吗?

Option Strict On
Option Explicit On
Imports System.ComponentModel
Imports System.IO
Imports System.Text

Public Class frmMain
Dim WithEvents bwWorkerThread As BackgroundWorker = New BackgroundWorker
Dim strFilePath As String 'record user selected file path

Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    bwWorkerThread.WorkerSupportsCancellation = True 'this thread can be stopped mid-process
    bwWorkerThread.WorkerReportsProgress = True 'this thread gives updates on how it is doing
End Sub

'When you click "Start"
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
    btnStart.Enabled = False 'disable start button, so user can't start it while it is still in progress
    btnStop.Enabled = True 'enable stop button, so user can stop it only after it has begun

    Dim ofdThreadTest As OpenFileDialog = New OpenFileDialog
    ofdThreadTest.CheckFileExists = True 'don't process fake files...
    ofdThreadTest.CheckPathExists = True '...or fake pathways
    ofdThreadTest.ReadOnlyChecked = True 'only read, no writing
    ofdThreadTest.ValidateNames = True 'don't process invalid names
    ofdThreadTest.Filter = "Files (*.dat)|*.dat" 'only allow the user to select and open the appropriate files

    If ofdThreadTest.ShowDialog() = DialogResult.OK Then 'only run if the user actually selects a file...
        strFilePath = ofdThreadTest.FileName '...store the file name and pathway to a string...
        Me.Text = ofdThreadTest.SafeFileName & " Loading Now..." '...let the user know we're loading...
        bwWorkerThread.RunWorkerAsync() '...then fire the bwWorkerThread DoWork event
    End If

End Sub

'When you click "Stop"
Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
    btnStart.Enabled = True 'enable the start button, so the user can restart the process after it has been stopped
    btnStop.Enabled = False 'disable the stop button, so that it can't be stopped when no longer in progress

    If bwWorkerThread.IsBusy Then 'if the thread is active...
        If bwWorkerThread.WorkerSupportsCancellation Then '...and it can be cancelled in-flight...
            bwWorkerThread.CancelAsync() '...kill the thread
        End If
    End If

End Sub

'Background Thread Main Task
Private Sub bwWorkerThread_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bwWorkerThread.DoWork


    Dim srFileTest As New IO.StreamReader(strFilePath)
    Dim strDelimter As String = "|"

    Dim intCounter As Integer = 0
    Dim intFileLength As Integer = _
        File.ReadAllLines(strFilePath).Length


    Try
        While srFileTest.Peek() >= 0

            If bwWorkerThread.CancellationPending Then
                e.Cancel = True
                Exit While
                Exit Try
            End If

            Dim strCurrentLine As String = srFileTest.ReadLine()
            Dim strEntry As String() = strCurrentLine.Split(strDelimter.ToCharArray())

            Dim objStore As New ExampleFile()

            objStore.DataPoint = strEntry(0)
            objStore.Process = strEntry(1)

            SetListBox_ThreadSafe(Me.listOne, objStore.DataPoint)
            SetListBox_ThreadSafe(Me.listTwo, objStore.Process)

            intCounter = intCounter + 1

            bwWorkerThread.ReportProgress(CInt((intCounter / intFileLength) * 100))

        End While
    Catch ex As Exception
        MessageBox.Show("Something unexpected happened!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

    MessageBox.Show(intFileLength.ToString)

End Sub

'Background Thread Progress Updates
Private Sub bwWorkerThread_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles bwWorkerThread.ProgressChanged

    Me.progMain.Value = e.ProgressPercentage
    Me.Text = e.ProgressPercentage.ToString & "% Finished"

End Sub

'Background Thread Finished
Private Sub bwWorkerThread_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles bwWorkerThread.RunWorkerCompleted
    If e.Cancelled Then
        Me.Text = "File Test - Operation Cancelled!"
    Else
        Me.Text = "File Test - Finished!"
    End If
End Sub

'Courier between bwWorkerThread and UI thread for list boxes
Delegate Sub SetListBox_Delegate(ByVal [ListBox] As ListBox, ByVal [value] As String)

Private Sub SetListBox_ThreadSafe(ByVal [ListBox] As ListBox, ByVal [value] As String)
    If [ListBox].InvokeRequired Then
        Dim MyListDelegate As New SetListBox_Delegate(AddressOf SetListBox_ThreadSafe)
        Me.Invoke(MyListDelegate, New Object() {[ListBox], [value]})
    Else
        [ListBox].Items.Add([value])
    End If
End Sub
End Class

'structure of example file in use
Public Class ExampleFile
    Public Property DataPoint As String
    Public Property Process As String
End Class

0 个答案:

没有答案