How to Stop and Restart a BackGroundWorker

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • LeoVBNET
    New Member
    • Apr 2013
    • 29

    How to Stop and Restart a BackGroundWorker

    Hi. I'm working on a project in which use a BackGroundWorke r control between two forms.

    I need to Cancel and immediately to restart the BackGroundorker from the same event. The problem is that: when BackGroundWorke r.CancelAsync() , apparently the thread does not cancel and when it gets to BackGroundWorke r.RunWorkerAsyn c(), the exception "BackgroundWork er is busy" is thrown.

    So, how can I cancel and restart the backgroundworke r from the same event.

    (Note: I tried with the Threading Class too and I got a similar problem. When use Thread.Abort() or Thread.Suspende d(), the thread is stopped but it cannot restart again.)
  • Mihail
    Contributor
    • Apr 2011
    • 759

    #2
    I try a response only because your post is 3 days older.
    Define a public variable. Say: Public StopRun As Boolean.
    Before starting the BackGroundorker set this variable to False.
    From the BackGroundorker verify from time to time this variable:
    If StopRun Then Exit

    Set to True this variable from the main code when you wish to stop the BackGroundorker .

    Sorry, my English is not very good. Hope you get the idea.

    Comment

    • LeoVBNET
      New Member
      • Apr 2013
      • 29

      #3
      Thanks Mihail but it does not work propertly. I used a boolean 'StopRun' and when it is applied from a button or from another independent method works, but remember I need to stop and restart the thread from the same method.
      Basically, I did StopRun on True, then sleep some milisecs and then StopRun on False and call the thread again. But the called method does not start from the begining or it just does not stop until finish.

      I'm still looking for.

      Comment

      • Mihail
        Contributor
        • Apr 2011
        • 759

        #4
        What you are trying to do ?
        Why you need to stop the BackGroundorker for miliseconds.
        Do you know the DoEvents statement ?

        If you explain WHY you wish to pause that BackGroundorker , maybe we can find a solution.

        Comment

        • LeoVBNET
          New Member
          • Apr 2013
          • 29

          #5
          Ok. I will try to be clear.
          See the code below:

          Code:
          Form_List
            -ListView
            Public Sub Fill_ListView()
              (every code to fill the ListView)
               Linq
               ImageList --> Module1.FindImage(Image As Bitmap)
               ListViewItem
               etc.
          
          ---------------------
          
          Form_PPAL
            Private MyList_1 As Form_List
            Private MyList_2 As Form_List
          
            Me.MyList_1.Fill_ListView
            Me.MyList_2.Fill_ListView
          Ok. The application of course has a lot of things I do not show. I just show you the important issue.

          The problem comes when it has to find each image of each item and there are a lot of items to show. It takes a lot of time. So, I suppose to use a thread to populate the ListViews.

          In the first sight the thread works fine but the user can switch a radios buttons ir order to visualize another items.

          So, just imagine when the user click on a radio button, the application has to stop the loading of items in either ListViews and then needs to start over again with populate de ListView with other items. That's all.

          Finally, I've heard about DoEvents but never have used it. I'm gonna try.

          Thanks.

          Comment

          • Mihail
            Contributor
            • Apr 2011
            • 759

            #6
            Yep.
            Seems that I have had a good feeling.
            I'm pretty sure that the DoEvents statement is the answer to your issue

            Say you have a long cycle:
            Code:
            For i = 1 to 1000000000000000000000000000000000
                For j = 1 to 1000000000000000000000000000000000
                    For k = 1 to 1000000000000000000000000000000000
                        DoEvents
                        'Other code
                    Next k
                Next j
            Next i
            MsgBox("OK - I have finished
            The DoEvents statement will allow you to do anything else with your computer WHILE the cycle IS RUNNING.
            No need to stop this cycle.
            And, when I say anything is really ANYTHING:
            You can see a movie, run other procedures, drink a beer :)

            Cheers !
            Last edited by Mihail; Jun 26 '13, 03:30 AM. Reason: Forget to add code tags

            Comment

            • LeoVBNET
              New Member
              • Apr 2013
              • 29

              #7
              jeje... I appreciate all your good intention. Really I do. But, my friend, that´s not the solution.

              When user changes a radiobutton option or wants to go to another place inside application, he should not wait for ListView loading. Besides, if user make two, three or more changes (clicks, etc), all of them are placed inside memory waiting to act. It is like when a program does not respond and suddenly every click you did appers one behind other and other.

              That's it. When user clicks radiobutton or any other button, the app must terminate the ListView loading, take de new values and then populates the ListView once again from benining with new values.

              It would be great if we can do something like this:

              Code:
              Private Sub Fill_ListView()
              
               If Thread1.ThreadState = Threading.ThreadState.Running Then
                  Thread1.Abort()
                  <some code>
               End If
              
               Thread1.Start()
              
              End Sub

              Comment

              • Mihail
                Contributor
                • Apr 2011
                • 759

                #8
                And this is fairly easy to obtain using DoEvents.

                Note that (see my previous post) you must allow events in the most interior cycle to ensure that DoEvents is executed with the maximum frequency.

                Put in a form 5 command buttons:
                cmdStart
                cmdPause
                cmdContinue
                cmdRestart
                cmdStop

                and in the Form module copy this code:

                Code:
                Option Compare Database
                Option Explicit
                
                Dim ThreadAction As String
                
                Private Sub cmdContinue_Click()
                    ThreadAction = "Continue"
                End Sub
                
                Private Sub cmdPause_Click()
                    ThreadAction = "Pause"
                End Sub
                
                Private Sub cmdRestart_Click()
                    ThreadAction = "Restart"
                End Sub
                
                Private Sub cmdStart_Click()
                    Call FillListView
                End Sub
                
                Private Sub cmdStop_Click()
                    ThreadAction = "Stop"
                End Sub
                
                Private Sub FillListView()
                    MsgBox ("Start cycle.")
                    
                    Do
                        MsgBox ("Now I read (new) values for variables and (new) settings")
                        ThreadAction = ""
                        Do
                            DoEvents
                            If ThreadAction = "Pause" Then
                                MsgBox ("I'll take a break")
                                Do While ThreadAction = "Pause"
                                    DoEvents
                                Loop
                                MsgBox ("The break was too short for me")
                            End If
                            If (ThreadAction = "Restart") Or (ThreadAction = "Stop") Then
                        Exit Do
                            End If
                        Loop
                    Loop Until ThreadAction = "Stop"
                    
                    MsgBox ("Stoped by user")
                End Sub

                Be sure that every command button "see" it's events.
                .
                .

                Comment

                • LeoVBNET
                  New Member
                  • Apr 2013
                  • 29

                  #9
                  It's ok when buttons is used. But that's not the idea.
                  If you want you can download a simple example I made in the next link:



                  'Threarding_1.z ip'

                  It is a very simple example, but it has the principal idea.

                  When user click on either button or changes radiobuttons, both ListView should stop their work and restart again from the begining.

                  Comment

                  • Mihail
                    Contributor
                    • Apr 2011
                    • 759

                    #10
                    I understand that.
                    But the radio button also has an event you can use: OnClick, OnChange, MouseDown, MouseUp etc.
                    I give you an idea about how DoEvents work.
                    If you don't wish even to try or you think that is a better way... Good luck !

                    Comment

                    • LeoVBNET
                      New Member
                      • Apr 2013
                      • 29

                      #11
                      In fact, I did try DoEvent but it was the same problem. Definitively, I gonna have to change the way I'm trying to do it.

                      Thanks again for your support.

                      Comment

                      • Killer42
                        Recognized Expert Expert
                        • Oct 2006
                        • 8429

                        #12
                        I'd just like to point out that you're likely to find much more useful information about threading in the VB.Net forum. This one is for VB6. VB6 is incredibly old, and threading was never much of an issue.

                        Comment

                        • txc2004
                          New Member
                          • Oct 2013
                          • 2

                          #13
                          Hello!

                          If you still need it,
                          Check this...

                          add 2 radiobuttons
                          add one textbox << this only for example put now
                          add one listbox << u later put listview
                          add one module

                          and use this code:

                          Code:
                          Public Class Form1
                          
                              Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
                                  txt = CType(sender, Control).Text
                          
                                  If work = False Then myEventHandler() Else restart = True '<< Important this line at the end only
                              End Sub
                          
                              Private Sub RadioButton1_Click(sender As Object, e As EventArgs) Handles RadioButton1.Click, RadioButton2.Click
                                  txt = CType(sender, RadioButton).Text
                          
                                  If work = False Then myEventHandler() Else restart = True '<< Important this line at the end only
                              End Sub
                          End Class
                          
                          
                          Module Module1
                              Public work As Boolean
                              Public restart As Boolean
                              Public i As Long
                              Public txt As String
                          
                              Public Sub myEventHandler()
                                  ' hear put the startup staff
                                  i = 0 : Form1.ListBox1.Items.Clear() : restart = False '<< start/restart staff
                                  Form1.Text = "Start"
                                  work = True
                          
                                  ' hear begin the core... !
                                  Do Until i = 10000
                                      Application.DoEvents()
                          
                                      ' hear put everything u need for restart
                                      If restart = True Then 'Reset
                                          i = 0 : Form1.ListBox1.Items.Clear() : restart = False '<< start/restart staff
                                      End If
                          
                                      ' hear is main work
                                      i = i + 1 : Form1.ListBox1.Items.Add(txt & "  " & Int(Rnd() * 999999))
                                      ' in this example put 10000 random numbers with sorted order
                                  Loop
                          
                                  ' and hear put the finish staff
                                  work = False
                                  Form1.Text = "Finish"
                              End Sub
                          
                          End Module

                          this is a basic idea...
                          propably if use this idea with background worker
                          have better results...

                          Comment

                          Working...