我正在尝试在Windows Phone 7上制作倒数计时器,这对我的应用程序非常重要。但我找不到任何方法来每秒更新UI规则中的文本。
Timer dt = new System.Threading.Timer(delegate
{
Dispatcher.BeginInvoke(() =>
{
newtime = oldtime--;
System.Diagnostics.Debug.WriteLine("#" + counter.ToString() +
" new: " + newtime.ToString() +
" old: " + oldtime.ToString());
counter++;
oldtime = newtime;
}
}, null, 0, 1000);
运行我的应用控制台输出后,如下所示:
#1 new: 445 old: 446 #2 new: 444 old: 445 #3 new: 445 old: 446 #4 new: 443 old: 444 #5 new: 444 old: 445 #6 new: 442 old: 443 #7 new: 443 old: 444 #8 new: 441 old: 442
我无法弄清楚如何摆脱那些不必要的调用(#3,#5,#7等)
感谢您的任何建议。
答案 0 :(得分:0)
您应该使用DispatcherTimer代替。以下示例显示了一个从十点开始倒计时的计时器。
DispatcherTimer _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
int _timeLeft = 10;
public MyClass()
{
InitializeComponent();
_timer.Tick += TimerTick;
_timer.Start();
MyTextBox.Text = _timeLeft.ToString();
}
void TimerTick(object sender, EventArgs e)
{
_timeLeft--;
if (_timeLeft == 0)
{
_timer.Stop();
MyTextBox.Text = null;
}
else
{
MyTextBox.Text = _timeLeft.ToString();
}
}
答案 1 :(得分:0)
尝试以下mod:
DispatcherTimer _timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) };
int _timeLeft = 50;
Stopwatch watch = new Stopwatch();
public MainPage()
{
InitializeComponent();
_timer.Tick += TimerTick;
_timer.Start();
textBlock1.Text = _timeLeft.ToString();
watch.Start();
}
void TimerTick(object sender, EventArgs e)
{
if ((_timeLeft - (int)watch.Elapsed.TotalSeconds) <= 0)
{
watch.Stop();
_timer.Stop();
textBlock1.Text = null;
}
else
{
textBlock1.Text = (_timeLeft - (int)watch.Elapsed.TotalSeconds).ToString();
}
}
顺便说一下Shawn的代码在我的设备上运行正常,但如果遇到问题,只需使用Stopwatch
并从时间变量中减去经过的时间。此外,运行DispatcherTimer
更快一点(当然对于这种技术),如200ms,以获得更高的准确性(一切都已在上面实现)。希望有所帮助。
答案 2 :(得分:0)
查看代码和注释时,我怀疑你的应用程序的错误不是使用Timer代码,而是使用任何初始化Timer - 我怀疑定时器正在被构造两次。
如果没有看到你发布的块之外的代码就很难调试它,但你描述的症状表明你正在初始化多个Timers和多个堆栈/闭包变量oldTime
和newTime
在简单的层面上,您可以尝试保护定时器结构 - 例如有类似的东西:
public class MyClass
{
// existing code...
private bool _timerStarted;
private void StartTimer()
{
if (_timerStarted)
{
Debug.WriteLine("Timer already started - ignoring");
return;
}
_timerStarted = true;
var newTime = 500;
var oldTime = 500;
var counter = 1;
Timer dt = new System.Threading.Timer(delegate
{
Dispatcher.BeginInvoke(() =>
{
newtime = oldtime--;
System.Diagnostics.Debug.WriteLine("#" + counter.ToString() +
" new: " + newtime.ToString() +
" old: " + oldtime.ToString());
counter++;
oldtime = newtime;
}
}, null, 0, 1000);
}
}