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 27
Eddie ShipmanAll-around developerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
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
Eddie ShipmanAll-around developerAuthor Commented:
I may just replace the BW's with Timers and that way I KNOW when they will fire.
0
JavaScript Best Practices

Save hours in development time and avoid common mistakes by learning the best practices to use for JavaScript.

Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
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 TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
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 TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
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
Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
"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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Eddie ShipmanAll-around developerAuthor Commented:
Whoa, I didn't know that. Thanks for the heads up..
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.