1

我正在尝试显示一个简单的第二个计数器。我有一个刻度间隔为 1 秒的调度程序计时器和一个文本框,我在刻度处理程序中使用当前秒数更新该文本框。在滴答处理程序中有少量工作,即在某些整数上调用“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();
    }
4

2 回答 2

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();
}
于 2013-03-29T08:21:36.770 回答
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(); });

    }
}
于 2013-03-28T17:12:28.960 回答