Link to home
Start Free TrialLog in
Avatar of chadmanvb
chadmanvb

asked on

How do I know when the background worker is done?

I have a background worker and need to process info once it's done.  I have a progress bar setup, but dont want to continue until the worker is done.  What should I add?

Try
            If Not BackgroundWorker1.IsBusy Then
               
                BackgroundWorker1.RunWorkerAsync()

            End If
            Dim intCounter As Integer = 0


            ProgressBar1.Maximum = 100

            ProgressBar1.Visible = True

            For x = 0 To 100 - 1

                System.Threading.Thread.Sleep(10)    'set delay for progress bar

                intCounter = intCounter + 1
                ProgressBar1.Value = intCounter
                Application.DoEvents()  'force progress bar update

            Next
           
            ProgressBar1.Visible = False

*******************need to stop here until worker is complete.*******

        Catch ex As Exception
            MsgBox(ex.Message)
            Exit Sub
        End Try
Avatar of John (Yiannis) Toutountzoglou
John (Yiannis) Toutountzoglou
Flag of Greece image

hi ...Check this ...
 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Try
            If Not BackgroundWorker1.IsBusy Then

                BackgroundWorker1.RunWorkerAsync()

            End If
                           

        Catch ex As Exception
            MsgBox(ex.Message)
            Exit Sub
        End Try
    End Sub

Open in new window

now the Do work event...
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim intCounter As Integer = 0
        ProgressBar1.Maximum = 100
        For x = 0 To 100 - 1
            System.Threading.Thread.Sleep(100)    'set delay for progress bar
            intCounter = intCounter + 1
            Me.Invoke(New IndicateValue(AddressOf IndicateBarValue), intCounter)
            BackgroundWorker1.ReportProgress(intCounter, x)
            Application.DoEvents()  'force progress bar update
        Next
    End Sub

Open in new window

Report Progress Event...
 Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        If e.ProgressPercentage = -1 Then
            MessageBox.Show(e.UserState)
        End If
        If e.ProgressPercentage = 100 Then
            MsgBox("done")
ProgressBar1.Visible=False
        End If
        ProgressBar1.Value = e.ProgressPercentage
        Me.Label1.Text += 1
    End Sub

Open in new window

Delegates
 Private Delegate Sub IndicateValue(ByVal value As Integer)
    Private Sub IndicateBarValue(ByVal int As Integer)
        ProgressBar1.Value = int
    End Sub

Open in new window

just set a label (Label1.text=0) to see the progress and BackgroundWorker ReportProgress to true (All these in formLoad)

Hope it helps...
John(Yiannis)
Avatar of Mike Tomlinson
Instead of checking for 100 as in:

    If e.ProgressPercentage = 100 Then

Handle the RunWorkerCompleted() event of the BackgroundWorker():
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercompleted.aspx

    "Occurs when the background operation has completed, has been canceled, or has raised an exception."

*This event is already marshaled to the main UI thread so you don't need to Invoke() from within it.
SOLUTION
Avatar of John (Yiannis) Toutountzoglou
John (Yiannis) Toutountzoglou
Flag of Greece image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
"e.Result" will only have something in it if you've actually assigned something to it from within the DoWork() handler.  You can use the RunWorkerCompleted() event by itself without necessarily having a "result", perhaps just as a place to reset the GUI controls.  =)
Avatar of chadmanvb
chadmanvb

ASKER

I just tried this and it seems to work ok.  Anything wrong with this?

Try
            If Not BackgroundWorker1.IsBusy Then

                BackgroundWorker1.RunWorkerAsync()

            End If
            ProgressBar1.Maximum = 100
            Do Until BackgroundWorker1.IsBusy = False

                Dim intCounter As Integer = 0

                For intCounter = 1 To 100 - 1
                    ProgressBar1.Visible = True



                    System.Threading.Thread.Sleep(30)    'set delay for progress bar

                    intCounter = intCounter + 1
                    ProgressBar1.Value = intCounter
                    Application.DoEvents()  'force progress bar update

                    If Not BackgroundWorker1.IsBusy Then
                        Exit Do
                    End If
                Next





            Loop

            ProgressBar1.Visible = False


        Catch ex As Exception
            MsgBox(ex.Message)
            Exit Sub
        End Try
" Anything wrong with this?"

Yes...you shouldn't do it that way.

Why have a BackgroundWorker() if you're just going to use a polling loop in the main UI thread?

Are you trying to animate the progressbar just to show that something is happening?  If so, just set it to "Marquee" mode.
I did this so I could show the progress bar.  I have a process that took about 2-3 seconds to run.  I moved that to the background so the progress bar could run on the main form.  Otherwise my other process would lock up the main form and the progress bar could not write to it.  Was there a better way to do this?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sorry for the delay, but thanks so much for the help!