Reputation: 1830
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?
Upvotes: 0
Views: 1148
Reputation: 29614
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)
.
Upvotes: 2
Reputation: 69272
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.
Upvotes: 1
Reputation: 3230
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();
}
});
}
Upvotes: 0