Search code examples
c#wpfdelaydispatchertimer

How do I add a delay after a count down timer


I am using a DispatcherTimer to perform a count down before triggering the release on a camera. The UpdateCountdown method is used to change the image displayed to the user before the camera fires. Rather than having the TakePicture method execute immediately, I would like have a slight delay after the counter reaches zero and the last image is displayed.

The code shown below results in the pause occurring at the _countdown = 1 point. While the final image displays and TakePicture() fires almost simultaneously (I think TakePicture happens first).

_countdownTimer = new DispatcherTimer();
_countdownTimer.Interval = TimeSpan.FromSeconds(1);
_countdownTimer.Tick += new EventHandler(delegate(object s, EventArgs a)
     { UpdateCountdown(); } );

_countdownTimer.Tick += new EventHandler(delegate(object s, EventArgs a)
     {if (_countdown == _countdownMax)
        {
            System.Threading.Thread.Sleep(2000);  // Slight delay before taking picture
            Camera.TakePicture();
        } });
    }

public void StartCountdown()
{
    if (doCount)
    {
        doCount = false;
        UpdateCountdown();
        _countdownTimer.Start();
    }
}

private void UpdateCountdown()
{
    _countdown--;
    CountdownImage = _countDownImages[_countdown]; // Data bound to Image Control

     if (_countdown == 0)
     {
       _countdown = _countdownMax;
       _countdownTimer.Stop();
       doCount = true;
      }

What am I not taking into account with my timing?


Solution

  • The UI does not update immediately when you change control properties - it only updates when the thread becomes idle (that is, after all your event handlers finish executing).

    Thread.Sleep blocks the thread, the event handlers don't finish executing and UI isn't redrawn.

    You have to either use another timer (start a new timer on the last tick of the existing timer and call TakePicture on teh new timer's tick) or, even better, use the last tick of the existing timer - update UI when (_countdown <= _countdownMax), take picture when (_countdown == _countdownMax + 1).