Solved

How do I know when the background worker is done?

Posted on 2013-02-06
9
364 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
ID: 38861918
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
ID: 38861950
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
ID: 38861976
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
Webinar: Aligning, Automating, Winning

Join Dan Russo, Senior Manager of Operations Intelligence, for an in-depth discussion on how Dealertrack, leading provider of integrated digital solutions for the automotive industry, transformed their DevOps processes to increase collaboration and move with greater velocity.

 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 38861985
"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
 

Author Comment

by:chadmanvb
ID: 38862098
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
ID: 38862273
" 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
ID: 38862389
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
ID: 38862576
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
ID: 38890296
Sorry for the delay, but thanks so much for the help!
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

809 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