Solved

How do I know when the background worker is done?

Posted on 2013-02-06
9
356 Views
Last Modified: 2013-02-14
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
0
Comment
Question by:chadmanvb
  • 4
  • 3
  • 2
9 Comments
 
LVL 18

Expert Comment

by:John (Yiannis) Toutountzoglou
Comment Utility
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)
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
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.
0
 
LVL 18

Assisted Solution

by:John (Yiannis) Toutountzoglou
John (Yiannis) Toutountzoglou earned 250 total points
Comment Utility
You are Absolutely Right..the RunWorkerCompleted raises a message but the e.result is empty.(should be ? when normal operation completed?)

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        If e.Cancelled Then
            ' The user canceled the operation.
            MessageBox.Show("Worker is cancelled")
        ElseIf (e.Error IsNot Nothing) Then
            ' There was an error during the operation.
            Dim msg As String = String.Format("An error occurred: {0}", e.Error.Message)
            MessageBox.Show(msg)
        Else
            ' The operation completed normally.
            Dim msg As String = String.Format("Result = {0}", e.Result)
            MessageBox.Show(msg)
        End If
    End Sub

Open in new window

Invoke() i' ve tried without invoking and gives me cross thread error...
Thank you mike for correcting me..
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
"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.  =)
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:chadmanvb
Comment Utility
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
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
" 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.
0
 

Author Comment

by:chadmanvb
Comment Utility
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?
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 250 total points
Comment Utility
Well...normally you don't hard-code a progress bar to move like that.  The "Marquee" style is used in cases where you don't know how long it will take, or if the process doesn't lend itself well to discrete steps that can report progress.

It would look something like:
Public Class Form1

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Try
            If Not BackgroundWorker1.IsBusy Then
                Button1.Enabled = False
                ProgressBar1.Visible = True
                ProgressBar1.Style = ProgressBarStyle.Marquee

                BackgroundWorker1.RunWorkerAsync()
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message)
            Exit Sub
        End Try
    End Sub

    Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        ' ...simulated two to three second work...
        System.Threading.Thread.Sleep(3000)
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        ProgressBar1.Style = ProgressBarStyle.Blocks
        ProgressBar1.Visible = False
        Button1.Enabled = True

        MessageBox.Show("Done!")
    End Sub

End Class

Open in new window


See ProgressBarStyle Enumeration:
http://msdn.microsoft.com/en-us/library/system.windows.forms.progressbarstyle.aspx

    "Marquee - Indicates progress by continuously scrolling a block across a ProgressBar in a marquee fashion."
0
 

Author Closing Comment

by:chadmanvb
Comment Utility
Sorry for the delay, but thanks so much for the help!
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now