使用计时器,秒表速度与计数变量不匹配 [英] Stop watch speed does not match with count variable using timer

查看:142
本文介绍了使用计时器,秒表速度与计数变量不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一个简单的C#应用​​程序。其中,我使用下面的代码。经过一段时间(3到4分钟),我看到秒表已经过了秒与timecount变量不匹配。

任何人都可以帮我解决下面代码中的错误吗?

 使用系统; 
使用 System.Collections.Generic;
使用 System.ComponentModel;
使用 System.Data;
使用 System.Drawing;
使用 System.Linq;
使用 System.Text;
使用 System.Windows.Forms;
使用 System.Diagnostics;

命名空间 TestApplication
{
public partial class TimerTest:表格
{
秒表_stopwatch = 秒表();
System.Timers.Timer TTTimer = new System.Timers.Timer( 1000 );
int timecount = 0 ;
public TimerTest()
{
InitializeComponent();

}

private void Startbtn_Click(< span class =code-keyword> object sender,EventArgs e)
{

this .TTTimer。 Interval = 1000 ; // 1秒
.TTTimer.Elapsed + = new System.Timers.ElapsedEventHandler(TTTimer_Elapsed);
this .TTTimer.Start();
// _stopwatch.Start();
}

void TTTimer_Elapsed( object sender,System.Timers.ElapsedEventArgs e)
{
if (!_stopwatch.IsRunning)
_stopwatch.Start();
this .Invoke((Action) delegate ()
{
label1.Text = _stopwatch.Elapsed.Hours +
+ _stopwatch.Elapsed .Minutes +
+ _stopwatch.Elapsed.Seconds
+ < span class =code-string> 计数: + timecount% 60 ;
});
timecount = timecount + 1 ; // timecount ++;
}
private void Stopbtn_Click( object sender,EventArgs e)
{
TTTimer.Stop();
_stopwatch.Stop();
_stopwatch.Reset();

}
}
}

解决方案

没有错误,或者没有真的。

计时器并不像你想象的那样准确 - 它是由事件驱动的,并且由于Windows是一个多任务,基于消息的系统而内置了固有的延迟。这意味着,虽然秒表值(每次读取时使用硬件时钟读取当前时间总是正确的,但是您在计时器中进行的任何计数都假设嘀嗒事件恰好每1秒发生一次 - 它不会发生' t。每次计时器打勾时尝试将时间打印到控制台,你会看到我的意思。



我建议你设置一个外部DateTime并在启动计时器时将其设置为DateTime.Now,然后计算Tick处理程序中的时差:

 Timespan diff = DateTime.Now  -  dateTimeWeStartedAt; 

而不是依靠自己计算滴答声。



顺便说一句:读这样的秒表值会偶尔引起视觉上的怪异 - 将Elapsed属性读入Timespan,然后使用它而不是多次读取,因为它可以在连续读取之间进行更改。在分钟,小时和结束时可能会发生重大更改天!


定时器不准确。看看这篇文章:计时器惊喜,以及如何避免它们 [ ^ ]。

I developed a simple C# application .In which , I used below code.After some time (3 to 4 min),I saw that Stop watch elapsed Second does not match with timecount variable.
Can anyone help me what is wrong in below code?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace TestApplication
{
    public partial class TimerTest : Form
    {
        Stopwatch _stopwatch = new Stopwatch();
        System.Timers.Timer TTTimer = new System.Timers.Timer(1000);
        int timecount = 0;
        public TimerTest()
        {
            InitializeComponent();

        }

        private void Startbtn_Click(object sender, EventArgs e)
        {
          
            this.TTTimer.Interval = 1000; //1 sec
            this.TTTimer.Elapsed += new System.Timers.ElapsedEventHandler(TTTimer_Elapsed);
            this.TTTimer.Start();
           // _stopwatch.Start();
        }

        void TTTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (!_stopwatch.IsRunning)
                _stopwatch.Start();
            this.Invoke((Action)delegate()
            {
                label1.Text = _stopwatch.Elapsed.Hours + ":" 
                             + _stopwatch.Elapsed.Minutes + ":" 
                             + _stopwatch.Elapsed.Seconds
                             + " Count: " + timecount % 60; 
            });
            timecount = timecount + 1; //timecount++;
        }
        private void Stopbtn_Click(object sender, EventArgs e)
        {
            TTTimer.Stop();           
            _stopwatch.Stop();
            _stopwatch.Reset();

        }
    }
}

解决方案

There is no error, or not really.
The Timer does not happen as accurately as you might think - it's event driven, and had inherent delays built in due to Windows being a multitasking, message-based system. This means that while the Stopwatch value (which uses a hardware clock to read the current time each time you read it will always be right, any counting you do in the timer assumes that the tick event happens exactly every 1 second - which it doesn't. Try printing the time to the console each time the timer ticks and you will see what I mean.

What I'd suggest is that you set up an external DateTime and set it to DateTime.Now when you start the timer, then work out the time difference in the Tick handler:

Timespan diff = DateTime.Now - dateTimeWeStartedAt;

Rather than relying on counting the ticks yourself.

BTW: Reading the Stopwatch value like that is going to throw up the occasional visual oddity - read the Elapsed property once into a Timespan, and then use that instead of reading it multiple times as it can change between successive reads. Significant changes can occur at the end of minutes, hours, and days!


Timers aren't accurate. Have a look at this article: "Timer surprises, and how to avoid them"[^].


这篇关于使用计时器,秒表速度与计数变量不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆