我正在尝试显示一个简单的第二个计数器。我有一个调度时间间隔为1秒的调度程序和一个文本框,我在tick处理程序中用当前的秒数更新。 tick处理程序中有很少的工作,即在某些int上调用'tostring()'。
我的问题是秒数比应该的慢。即使我将间隔设置为100毫秒并在经过时进行检查,它仍然比它应该更慢。 (在一分钟内它大约慢了6秒)。
有人能指出我正确的方向显示准确的第二个计数器吗?
编辑:这里有一些代码(在.xaml.cs中)。它取自一个工作正常的例子。不同之处在于我设置了TextBox的Text属性,而不是另一个控件的Value属性。
...
this.timer.Interval = TimeSpan.FromMilliseconds(100);
...
private void OnDispatcherTimer_Tick(object sender, EventArgs e) {
if (this.currentValue > TimeSpan.Zero) {
this.currentValue = this.currentValue.Value.Subtract(TimeSpan.FromMilliseconds(100));
} else {
// stop timer etc
}
this.seconds.Text = this.currentValue.Value.Seconds.ToString();
}
答案 0 :(得分:8)
你跟踪时间的方式是有缺陷的。每次计时器滴答时,您都在递增一个计数器,但不能保证您的计时器每100毫秒执行一次。即使它确实如此,您也必须考虑代码的执行时间。因此,无论你做什么,你的计数器都会漂移。
您必须做的是存储您启动柜台的日期。然后,每次计时器滴答时,您计算已经过的秒数:
private DateTime TimerStart { get; set; }
private void SomePlaceInYourCode()
{
this.TimerStart = DateTime.Now;
// Create and start the DispatcherTimer
}
private void OnDispatcherTimer_Tick(object sender, EventArgs e) {
var currentValue = DateTime.Now - this.TimerStart;
this.seconds.Text = currentValue.Seconds.ToString();
}
答案 1 :(得分:1)
如果你关心准确的时间,那么调度员就不是一个好的选择。
我应该分开计数秒(时间)并在屏幕上显示。
使用System.Threading.Timer并在Timer回调中使用Dispatcher.BeginInvoke()。
简单的例子:
public partial class MainPage : PhoneApplicationPage
{
private DateTime _startDate;
private int _secondDuration;
private Timer _timer;
// Constructor
public MainPage()
{
InitializeComponent();
_startDate = DateTime.Now;
_secondDuration = 0;
_timer= new Timer(timerCallback, null, 0, 10);
}
private void timerCallback(object state)
{
var now = DateTime.Now;
if (now > _startDate + TimeSpan.FromSeconds(1))
{
_secondDuration += 1;
_startDate = now;
Dispatcher.BeginInvoke(() => { Counter.Text = _secondDuration.ToString(); });
}
}
}
每隔10毫秒计时器检查一秒后,打印到文本框经过几秒钟
或者您可以这样做:
public partial class MainPage : PhoneApplicationPage
{
private Timer _timer;
private int _secondDuration;
// Constructor
public MainPage()
{
InitializeComponent();
_timer = new Timer(timerCallback, null, 0, 1000);
}
private void timerCallback(object state)
{
_secondDuration += 1;
Dispatcher.BeginInvoke(() => { Counter.Text = _secondDuration.ToString(); });
}
}