0

During the startup of my app I am doing a long database upgrade. Before that starts, I show a form that has a progressbar so that the user knows that something is going on and he should wait.

To not block the progressbar from redrawing, I do the database upgrade in a background worker.

The code looks like this:

            frmMain_Load(...)

            Dim wait As New frmWait
            wait.Show()

            Dim bw As New frmBWRebuildUserData
            bw.Start()
            Do While Not bw.Done
                System.Threading.Thread.Sleep(100)
            Loop

            'Okay, db update was done, now continue and show the main app window

My frmBWRebuildUserData looks like this:

Public Class frmBWRebuildUserData

Private m_bDone As Boolean

Public ReadOnly Property Done() As Boolean

    Get
        Return m_bDone
    End Get

End Property

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    modAppDB.RebuildUserDB()

End Sub
Public Sub Start()

    Me.BackgroundWorker1.RunWorkerAsync()

End Sub

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

    m_bDone = True

End Sub
End Class

But after 60 seconds, VB.NET tells me that there were no messages since 60 seconds (I guess you know this error).

But since the background worker is intended for such purposes, I think I am doing something substantially wrong here, but I can't figure out what.

Also, my progressbar is not redrawing.

Can somebody help, please? Thank you very much!

tmighty
  • 10,734
  • 21
  • 104
  • 218
  • Do you have 3 forms in this example? What is the purpose of each one? Where is the progressbar shown? – Steve Dec 21 '12 at 10:08

2 Answers2

1

A couple of things.

There is no built in timeout of 60 seconds in the backgroundworker. So it should be something in your code.

Why do you use a backgroundWorker and then introduce in your code a sleep cycle? The backgroundworker should be used to free the user interface from waiting for the end of long operations.

The backgroundworker when asked to report its progress to a user interface element needs something like this (sorry is C#, but I think you can get the point)

 backgroundworker.ProgressChanged += backgroundworker_ProgressChanged;
 backgroundworker.WorkerReportsProgress = true;

in this scenario your modAppDB.RebuildUserDB() need to call

 backgroundworker.ReportProgress(percentComplete);

for every step that you want to communicate to the progress bar and of course, you need in the form where the progressbar is displayed to intercept the event fired by the ReportProgress call

private void backgroundworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = (e.ProgressPercentage.ToString() + "%");
}
Steve
  • 213,761
  • 22
  • 232
  • 286
  • It may be possible that it is something in my code. For example I noticed that the database (a COM object) is declared publicly, and I try to use it within the background worker. I guess that may be causing problems. I just let the progressbar flow continuously, I didn't want to update by the background worker. – tmighty Dec 21 '12 at 10:22
1

The Backgroundworker is mainly good for tasks where you have a loop inside DoWork, which allows you to do some UI feedback within the loop. If your DoWork just calls another command, it will wait for this command to finish and not do anything in this time. Other than that, using the BGW still allows for the main thread to handle its messages and not get blocked, so I presume it is still entirely right to use it here.
Apart from that, your backgroundworker1 is not declared, and as Steve pointed out, your Start()-Method needs at least this first line:
Addhandler Backgroundworker1.DoWork, AddressOf BackgroundWorker1_DoWork. This triggers the function when RunworkerAsync is called.
For a basic example of thread-communication (and fundamental problems connected with it) take a look at this question and answer:
Multithreading for a progressbar and code locations (vb.net)?
I don't know about the 60 seconds issue either.

Community
  • 1
  • 1
KekuSemau
  • 6,830
  • 4
  • 24
  • 34
  • Thank you. I dragged a BackgroundWorker from the Toolbox onto my form. Isn't that enough for a declaration? – tmighty Dec 21 '12 at 12:24
  • Sorry, I can not set 2 replies as "the answer", so I have chosen the first posted. But both of your replies were great, thank you! – tmighty Dec 21 '12 at 16:11