Nim
Nim

Reputation: 376

The Timer Tick isn't triggered despite timer start.

Timer won't ticket I can work out why, I've included the various sections of code.

using Timer = System.Windows.Forms.Timer;

Then inside my class (internal sealed)

Declared

 private int _timeLeft;
    Timer _countDownTimer = new Timer();
    private int _scriptsLeftCount;

Then inside Method

_timeLeft = timeToStart;
            _countDownTimer.Tick += CountDownTimer_Tick;
            _countDownTimer.Interval = 60000;
            _countDownTimer.Start();

    private void CountDownTimer_Tick(object sender, EventArgs e)
    {
        Console.WriteLine("Tick " + _timeLeft);
        if (_timeLeft > 0)
        {
            // Display the new time left 
            // by updating the Time Left label.
            _timeLeft = _timeLeft - 1;
            WriteMessage(_timeLeft + " Minutes" + Environment.NewLine);
        }
        else
        {
            _countDownTimer.Stop();
            Restore();
        }
    }

Yet it doesn't seem to do any of the tick. Subsiquently not running restore, any pointers would be helpful.

Upvotes: 0

Views: 148

Answers (1)

Nim
Nim

Reputation: 376

The reason it doesn't work is that the WinForms timer runs in the UI thread, and background workers run in a background thread.

That said, you shouldn't be doing it. A background worker shouldn't need to wait for timed periods; if you have something that happens at timed intervals, you can have a timer in the main thread and start new work items when it fires. If you want to wait for input in a background worker, you can use a blocking I/O call. If it needs to wait for some other item to be complete, use EventWaitHandles (Manual- or AutoResetEvents).

However that being said,

If you want to do something repeatedly, you should just use a loop inside the backgroundworker DoWork() method.

private void DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    int delay = 1000; // 1 second
    while (!worker.CancellationPending)
    {
        do something
        Thread.Sleep(delay);
    }
    e.Cancel = true;
}

If you need a delay longer than 1 second, your loop will have to change a little to allow you to detect whether or not the worker has been closed:

int delay = 1000; // 1 second
    int interval = 60000;
    int elapsed = 0;
    while (!worker.CancellationPending)
    {
        elapsed = 0;
        do {
          Thread.Sleep(delay);
        }
        while (elapsed < interval && !worker.CancellationPending);
    }
    e.Cancel = true;

Upvotes: 2

Related Questions