2

I am trying to build a log parser in VB.Net that will take IIS logs and insert them into a database. Having never really made a full out desktop application, I'm hitting a number of stumbling blocks, so please forgive me if my questions a very uninformed; I'm learning to walk while running.

The code that I'm working with looks like this:

 Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
    MyBase.OnLoad(e)
    BackgroundWorker1.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim logfile = "C:\ex111124.log"
    Dim FileLength As Long = New System.IO.FileInfo(logfile).Length
    logFileLabel.Text = logfile

    Dim objReader As New System.IO.StreamReader(logfile)
    Do While objReader.Peek() <> -1
        OngoingLog.AppendText(objReader.ReadLine)
        'BackgroundWorker1.ReportProgress(e.percentProgress)
        Loop()
    objReader.Close()
    objReader = Nothing

End Sub

Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    'Me.crunchingProgress.Value = e.ProgressPercentage
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    Close()
End Sub

So the function works, when this window is opened it starts to read the log file and updates a textbox with all of the rows currently read, but I also want it to update a progress bar in my main thread called crunchingProgress.

Any help would be greatly appreciated.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
J_D
  • 681
  • 2
  • 8
  • 22

2 Answers2

2

This should do the trick:

Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    Invoke(Sub()
        Me.crunchingProgress.Value = e.ProgressPercentage
    End Sub)
End Sub
w.brian
  • 16,296
  • 14
  • 69
  • 118
  • Thanks, this worked along with adding some calls to delegate other control updates in thread safe subs – J_D Mar 11 '13 at 19:38
  • 1
    You don't need to call Invoke on a ProgressChanged event. It is fired in the same thread where the RunWorkerAsync is called (usually the UI thread). http://stackoverflow.com/questions/1968222/backgroundworker-still-needs-to-call-invoke – Steve Mar 11 '13 at 19:53
2

You don't set the BackgroundWorker to report progress (WorkerReportsProgress)

BackgroundWorker1.WorkerReportsProgress = True
BackgroundWorker1.RunWorkerAsync()

Now your BackgroundWorker1_ProgressChanged will be called in the context of the UI Thread and you can set the progressbar value

Of course, when you call ReportProgress to raise the ProgressChanged event, you need to pass the percentage of work done so far.

Using objReader As New System.IO.StreamReader(logfile)
    Do While objReader.Peek() <> -1
        Dim line = objReader.ReadLine()
        OngoingLog.AppendText(line)
        Dim pct = Convert.ToInt32((100 * line.Length) / FileLength )
        BackgroundWorker1.ReportProgress(pct)
    Loop
End Using
Steve
  • 213,761
  • 22
  • 232
  • 286
  • I'm using Visual Studio, so I set the two properties via the UI per another tutorial I was reading. I did realize that I needed to feed something ProgressChanged event after submitting my question, but thanks for giving me a good direction to head in for calculating it. – J_D Mar 11 '13 at 19:35