Can't understand Backgroundworker and intervals

We have 10 BackgroundWorkers in a project.
We have DoWork events on a couple and we also we want them to "sleep" for a specified period of time before
actually running again.

We do this at the end of the DoWork in one of the backgroundworkers named bwPatientRequests:
  System.Threading.Thread.Sleep(INTERVAL_PatientRequests) 'INTERVAL_PatientRequests = 180000
Doesn't this mean this thing should sleep for 3 min before it runs again.

Why is this one and another one running every minute?
We have one other one whose interval is set to one minute and in each of the ones we want to sleep we have a RunWorkerCompleted event and call Application.DoEvents() in each of them.

Any idea how we can make them have different intervals and sleep accordingly?

bwVisitRequests - should sleep 3 minutes (INTERVAL_VisitRequsts = 180000)
bwPatientRequests - should sleep 3 minutes (INTERVAL_PatientRequests = 180000)
bwProcessMessages - should sleep 1 minute. (INTERVAL_ProcessMessages = 10000)

bwProcessMessages processes the messages retrieved by the other two workers at their intevals.
LVL 26
Eddie ShipmanAll-around developerAsked:
Who is Participating?
 
Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
"I moved the sleep for the whole worker to the RunWorkCompleted before the RunAsync gets called again."

But the RunWorkCompleted() event actually runs in the MAIN UI THREAD...so if you make it Sleep you will be locking up your Form!  =\
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
How are the background workers on your form?...Did you drop them there are design-time?...Are you creating them dynamically at run-time?
0
 
Eddie ShipmanAll-around developerAuthor Commented:
Dropped on form. I didn't create this project, just debugging trying to figure out why it
is polling every minute .vs 3 minutes like we want.
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

 
Eddie ShipmanAll-around developerAuthor Commented:
I may just replace the BW's with Timers and that way I KNOW when they will fire.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Well...BackgroundWorkers don't restart themselves...they must be explicitly started with code.  How are they being launched?...can u show that code please?
0
 
Eddie ShipmanAll-around developerAuthor Commented:
They are restarted in the RunWorkerCompleted events like this:

    Private Sub bwVisitRequests_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwVisitRequests.RunWorkerCompleted
        If iVisitRequestErrorCount > 10 Then
            LogErrorToFile("MORE THAN 10 ERRORS HAVE OCCURRED ON GETUPDATEDVISIT REQUEST.  STOPPED THIS CHANNEL AT " & Now.ToString, sFilePath & "\ErrorLog.txt")
        Else
            If blnStop = False AndAlso blnStopVisit = False Then bwVisitRequests.RunWorkerAsync()
            LogErrorToFile(STOPERROR, sFilePath & "\ErrorLog.txt")
            Application.DoEvents()
        End If
    End Sub

Open in new window

0
 
Eddie ShipmanAll-around developerAuthor Commented:
Initially started like this:
    Me.bwPatientRequests.RunWorkerAsync()
    Me.bwVisitRequests.RunWorkerAsync()
    Me.bwProcessMessages.RunWorkerAsync()

Open in new window

0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
The concept seems to work for me...can you do some testing with a simple project?

This is what I get:
BGW..2
BGW.1
BGW...3
BGW.1
BGW.1
BGW.1
BGW.1
BGW..2
BGW.1
BGW.1
BGW.1
BGW.1
BGW.1
BGW..2
BGW.1
BGW...3
etc...
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        BackgroundWorker1.RunWorkerAsync()
        BackgroundWorker2.RunWorkerAsync()
        BackgroundWorker3.RunWorkerAsync()
    End Sub
 
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Debug.Print("BGW.1")
        System.Threading.Thread.Sleep(1000)
    End Sub
 
    Private Sub BackgroundWorker2_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.DoWork
        Debug.Print("BGW..2")
        System.Threading.Thread.Sleep(5000)
    End Sub
 
    Private Sub BackgroundWorker3_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker3.DoWork
        Debug.Print("BGW...3")
        System.Threading.Thread.Sleep(10000)
    End Sub
 
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        BackgroundWorker1.RunWorkerAsync()
    End Sub
 
    Private Sub BackgroundWorker2_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker2.RunWorkerCompleted
        BackgroundWorker2.RunWorkerAsync()
    End Sub
 
    Private Sub BackgroundWorker3_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker3.RunWorkerCompleted
        BackgroundWorker3.RunWorkerAsync()
    End Sub
 
End Class

Open in new window

0
 
Eddie ShipmanAll-around developerAuthor Commented:
We have found the problem. In one of the DoWork events, we are sending requests in a while
loop. But, even if I put another Sleep INSIDE the loop, it still fires every 2-15 seconds. Is there a way for me to make a while loop stop for a specified period of time?
0
 
Eddie ShipmanAll-around developerAuthor Commented:
See code below...
Private Sub bwVisitRequests_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwVisitRequests.DoWork
  Try
    Dim SDATE As Object = Me.ILynxPMTableAdapter_VisitRequests.GETLASTMESSAGETIME("GETUPDATEDVISITS")
    If Me.CoSettingsTableAdapter1.GetValue("InitialVisitLoadComplete").ToUpper <> "TRUE" Then    'initial data load
        'start 1 year back and go 1 year forward
        Dim myDate As DateTime = Now.AddDays(-365)
        Dim myLastDate As String = Me.CoPracticeSettingsTableAdapter1.GetValue("InitialVisitLoadComplete").ToUpper
        If IsDate(myLastDate) Then myDate = CDate(myLastDate).AddDays(1)
   
        While myDate < Now.AddDays(365)
            ' Do the message send/receive here
            ' Now update the settings table with the date
            CoSettingsTableAdapter1.UpdateQuery(myDate.ToString("MM/dd/yyyy"), "InitialVisitLoadComplete")
            ' Sleep the thread
            System.Threading.Thread.Sleep(30000)
            ' and update the date to process next day's messages
            myDate = myDate.AddDays(1)
        End While
    Else
      ' do something else
    End If
    iVisitRequestErrorCount = 0
  Catch ex As Exception
    LogErrorToFile("Error on visit request:  " & ex.ToString, sFilePath & "\ErrorLog.txt")
    iVisitRequestErrorCount += 1
  Finally
    System.Threading.Thread.Sleep(INTERVAL_VisitRequests) ' INTERVAL_VisitRequests = 180000
  End Try
End Sub

Open in new window

0
 
Eddie ShipmanAll-around developerAuthor Commented:
The 30 second sleep inside the loop is not working.
Any ideas?
0
 
Eddie ShipmanAll-around developerAuthor Commented:
Would this work?
Dim mytime As Integer = Date.Now.Second
Dim waittime As Integer = Date.Now.Second + 30000
While mytime < waittime
  mytime = Date.Now.Second
End While

Open in new window

0
 
Eddie ShipmanAll-around developerAuthor Commented:
Well, according to the test posted below, the way we have our code written, it *should* work.
Can you see anything in our code above that may be wrong?
I also posted the bwVisitRequests_RunWorkerCompleted below.
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.BackgroundWorker1.RunWorkerAsync()
    End Sub
 
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        Me.BackgroundWorker1.RunWorkerAsync()
    End Sub
 
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim mydate As DateTime = Date.Now
        Try
            Debug.Print(String.Format("mydate outside {0:F}", mydate))
            While mydate < Now.AddDays(5)
                Dim mytime As DateTime = Date.Now
                Debug.Print("mytime {0:F}", mytime)
                System.Threading.Thread.Sleep(10000)
                mydate = mydate.AddDays(1)
                Debug.Print(String.Format("mydate inside {0:F}", mydate))
            End While
        Finally
            System.Threading.Thread.Sleep(30000)
        End Try
    End Sub
End Class
 
'Results:
mydate outside Thursday, November 13, 2008 11:36:44 AM
mytime Thursday, 13 November 2008 11:36:44
mydate inside Friday, November 14, 2008 11:36:44 AM
mytime Thursday, 13 November 2008 11:36:54
mydate inside Saturday, November 15, 2008 11:36:44 AM
mytime Thursday, 13 November 2008 11:37:04
mydate inside Sunday, November 16, 2008 11:36:44 AM
mytime Thursday, 13 November 2008 11:37:14
mydate inside Monday, November 17, 2008 11:36:44 AM
mytime Thursday, 13 November 2008 11:37:24
mydate inside Tuesday, November 18, 2008 11:36:44 AM
mytime Thursday, 13 November 2008 11:37:34
mydate inside Wednesday, November 19, 2008 11:36:44 AM
' here is where the 30 second sleep occurs
mydate outside Thursday, November 13, 2008 11:38:14 AM
mytime Thursday, 13 November 2008 11:38:14
mydate inside Friday, November 14, 2008 11:38:14 AM
mytime Thursday, 13 November 2008 11:38:24
mydate inside Saturday, November 15, 2008 11:38:14 AM
mytime Thursday, 13 November 2008 11:38:34
mydate inside Sunday, November 16, 2008 11:38:14 AM
mytime Thursday, 13 November 2008 11:38:44
mydate inside Monday, November 17, 2008 11:38:14 AM
mytime Thursday, 13 November 2008 11:38:54
mydate inside Tuesday, November 18, 2008 11:38:14 AM
mytime Thursday, 13 November 2008 11:39:04
mydate inside Wednesday, November 19, 2008 11:38:14 AM
' here is where the 30 second sleep occurs
mydate outside Thursday, November 13, 2008 11:39:44 AM
 
    Private Sub bwVisitRequests_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwVisitRequests.RunWorkerCompleted
        If iVisitRequestErrorCount > 10 Then
            LogErrorToFile("MORE THAN 10 ERRORS HAVE OCCURRED ON GETUPDATEDVISIT REQUEST.  STOPPED THIS CHANNEL AT " & Now.ToString, sFilePath & "\ErrorLog.txt")
        Else
            If blnStop = False AndAlso blnStopVisit = False Then bwVisitRequests.RunWorkerAsync()
            LogErrorToFile(STOPERROR, sFilePath & "\ErrorLog.txt")
            Application.DoEvents()
        End If
    End Sub

Open in new window

0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Nothing is popping out at me...  =\

I would change this:

    While myDate < Now.AddDays(365)

To this though:

    Dim targetDT As DateTime = Now.AddDays(365)
    While myDate < targetDT
0
 
Eddie ShipmanAll-around developerAuthor Commented:
I have found that separating the code within the DOWork, in particular the one with the While loop has made things work like we want, including sleeping within the while loop and sleeping after the while loop is done. I moved the sleep for the whole worker to the RunWorkCompleted before the RunAsync gets called again.

Things look like they work as expected, now.
0
 
Eddie ShipmanAll-around developerAuthor Commented:
Whoa, I didn't know that. Thanks for the heads up..
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.