I am writing an app which uses a timer to display a countdown on screen to when some event happens. I want to reuse the timer, as it would be handy for a few things in the app, so I specify the words I want to wrap round the timer. For example, the following function call:
CountdownTimer(90, "You have ", " until the computer reboots");
would show:
You have 1 minute 30 seconds until the computer reboots
and then count down.
I am using the following code:
private void CountdownTimer(int Duration, string Prefix, string Suffix)
{
Countdown = new DispatcherTimer();
Countdown.Tick += new EventHandler(Countdown_Tick);
Countdown.Interval = new TimeSpan(0, 0, 1);
CountdownTime = Duration;
CountdownPrefix = Prefix;
CountdownSuffix = Suffix;
Countdown.Start();
}
private void Countdown_Tick(object sender, EventArgs e)
{
CountdownTime--;
if (CountdownTime > 0)
{
int seconds = CountdownTime % 60;
int minutes = CountdownTime / 60;
Timer.Content = CountdownPrefix;
if (minutes != 0)
{
Timer.Content = Timer.Content + minutes.ToString() + @" minute";
if (minutes != 1) { Timer.Content = Timer.Content + @"s"; }
Timer.Content = Timer.Content + " ";
}
if (seconds != 0)
{
Timer.Content = Timer.Content + seconds.ToString() + @" second";
if (seconds != 1) { Timer.Content = Timer.Content + @"s"; }
}
Timer.Content = Timer.Content + CountdownSuffix;
}
else
{
Countdown.Stop();
}
}
How do I make this run synchronously? For example I would want the following to wait 90 seconds开发者_StackOverflow社区 and then reboot:
CountdownTimer(90, "You have ", " until the computer reboots");
ExitWindowsEx(2,0)
Whereas it calls the reboot immediately at present.
Any pointers would be most welcome!
Thanks,
Ben
Personally, I'd recommend having a callback happen at the end of your CountdownTimer - perhaps taking an Action
as an argument, such that when it completed it'd be called.
private Action onCompleted;
private void CountdownTimer(int Duration, string Prefix, string Suffix, Action callback)
{
Countdown = new DispatcherTimer();
Countdown.Tick += new EventHandler(Countdown_Tick);
Countdown.Interval = new TimeSpan(0, 0, 1);
CountdownTime = Duration;
CountdownPrefix = Prefix;
CountdownSuffix = Suffix;
Countdown.Start();
this.onCompleted = callback;
}
...
else
{
Countdown.Stop();
Action temp = this.onCompleted; // thread-safe test for null delegates
if (temp != null)
{
temp();
}
}
Then you could just change your usage to:
CountdownTimer(90, "You have ", " until the computer reboots",
() => ExitWindowsEx(2,0));
You could use an AutoResetEvent:
System.Threading.AutoResetEvent _countdownFinishedEvent
= new AutoResetEvent(false);
Add this at the end of CountdownTimer
:
_countdownFinishedEvent.WaitOne();
And add this inside the else of Countdown_Tick
just after Countdown.Stop()
:
_countdownFinishedEvent.Set();
精彩评论