Question

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?

Was it helpful?

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).

OTHER TIPS

Why not just make your display always show 1 less than the number of seconds remaining. That way when you get to zero, (obviously with a Math.Max(0, _countdown) to prevent showing -1) it will seem like the time has run out even though there's one more second to go.

Edit: What I meant to imply but did not state - was that you could then just have one Tick handler and not use Sleep at all which will just wind up blocking the UI anyway which will probably block your UI from updating.

I don't think that events guarantee that event handlers are triggered in the order that they are registered. Try

_countdownTimer.Tick += new EventHandler(delegate(object s, EventArgs a)     
{
        UpdateCountdown();
        if (_countdown == _countdownMax)
        {
            System.Threading.Thread.Sleep(2000);  // Slight delay before taking picture
            Camera.TakePicture();
        }
      });
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top