Timer not firing correctly - strange problem....

J

Johnny Jörgensen

I've got a process I want to run in a thread separate from my main
application thread, so I've used a backgroundworker component, and in
frmMain.Load I invoke the code using Backgroundworker1.RunWorkerAsync().

So far so good, this works fine. But when the process is done, I want to
wait 30 minutes and then run the process again. So I added a
System.Windows.Forms.Timer component to the form and in the
Backgroundworker1_RunWorkerCompleted event, I start the timer like this:

Timer1.Interval = 3600000; //3600000 ms = 60 minutes
Timer1.Enabled = true;

in the Timer1_Tick event, I simply start the backgroundworker again using
Backgroundworker1.RunWorkerAsync()

I would expect the timer to run for an hour and then restart the
backgroundworker, but what really happens is that the Timer1_Tick event
fires after a very short time, between 20 and 30 seconds (and not the same
interval every time; The first time it happens, it can be 22 seconds, the
next 28 seconds etc. - no pattern).

WHY IS THAT? I cannot for the life of me explain what happens. First I
thought there was a problem with the Timer component, so I tried to create e
new timer instance every time I got to the
Backgroundworker1_RunWorkerCompleted event, but that didn't help - same
thing happened.

Then I thought: Well, maybe it has something to do with the fact that the
background thread disposes after a short interval when the process is over,
but even if that's the case, it ought not interfere with the timer since
code in the Backgroundworker1_RunWorkerCompleted event (as far as I know) is
executed in the main application thread, and the timer itself is created in
the main applcation thread. And just because it fires prematurely, the
component still exists - it's not disposed of.

Has anybody got an explanation, and what can I do to avoid the problem?

TIA,
Johnny J.
 
C

Ciaran O''Donnell

Just a suggestion but have you tried using a System.Timers.Timer. The
difference is that the Elasped event is raised on a threadpool thread so you
wouldnt have to control the async behaviour yourself. You could set the timer
originally with an interval of 100, then on elasped, stop the timer, do the
work in the same thread, the set the interval to 360000 and restart the
timer.
If you were using a Windows.Forms.Timer to enable you to update the UI, you
can use Control.Invoke to do that from the background thread the timer uses.
This is how I would have approached it and I believe I have done this in the
past with no issues.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top