C# 为什么定时器频率非常低? [英] C# Why are timer frequencies extremely off?

查看:21
本文介绍了C# 为什么定时器频率非常低?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

System.Timers.TimerSystem.Threading.Timer 的触发间隔与请求的间隔有很大不同.例如:

Both System.Timers.Timer and System.Threading.Timer fire at intervals that are considerable different from the requested ones. For example:

new System.Timers.Timer(1000d / 20);

产生一个每秒触发 16 次而不是 20 次的计时器.

yields a timer that fires 16 times per second, not 20.

为了确保不会因过长的事件处理程序产生副作用,我编写了这个小测试程序:

To be sure that there are no side-effects from too long event handlers, I wrote this little test program:

int[] frequencies = { 5, 10, 15, 20, 30, 50, 75, 100, 200, 500 };

// Test System.Timers.Timer
foreach (int frequency in frequencies)
{
    int count = 0;

    // Initialize timer
    System.Timers.Timer timer = new System.Timers.Timer(1000d / frequency);
    timer.Elapsed += delegate { Interlocked.Increment(ref count); };

    // Count for 10 seconds
    DateTime start = DateTime.Now;
    timer.Enabled = true;
    while (DateTime.Now < start + TimeSpan.FromSeconds(10))
        Thread.Sleep(10);
    timer.Enabled = false;

    // Calculate actual frequency
    Console.WriteLine(
        "Requested frequency: {0}
Actual frequency: {1}
",
        frequency, count / 10d);
}

输出如下:

请求:5赫兹;实际:4,8 赫兹
要求:10赫兹;实际:9,1 赫兹
要求:15赫兹;实际:12,7 Hz
要求:20赫兹;实际:16 赫兹
要求:30赫兹;实际:21,3 Hz
要求:50赫兹;实际:31,8 Hz
要求:75赫兹;实际:63,9 Hz
要求:100赫兹;实际:63,8 Hz
要求:200赫兹;实际:63,9 Hz
要求:500赫兹;实际:63,9 Hz

Requested: 5 Hz; actual: 4,8 Hz
Requested: 10 Hz; actual: 9,1 Hz
Requested: 15 Hz; actual: 12,7 Hz
Requested: 20 Hz; actual: 16 Hz
Requested: 30 Hz; actual: 21,3 Hz
Requested: 50 Hz; actual: 31,8 Hz
Requested: 75 Hz; actual: 63,9 Hz
Requested: 100 Hz; actual: 63,8 Hz
Requested: 200 Hz; actual: 63,9 Hz
Requested: 500 Hz; actual: 63,9 Hz

实际频率与请求的频率偏差高达 36%.(并且显然不能超过 64 Hz.)鉴于 Microsoft 推荐此计时器是因为它比 System.Windows.Forms.Timer 具有更高的准确性",这让我感到困惑.

The actual frequency deviates by up to 36% from the requested one. (And evidently cannot exceed 64 Hz.) Given that Microsoft recommends this timer for its "greater accuracy" over System.Windows.Forms.Timer, this puzzles me.

顺便说一句,这些不是随机偏差.它们每次都是相同的值.另一个计时器类的类似测试程序 System.Threading.Timer 显示了完全相同的结果.

Btw, these are not random deviations. They are the same values every time. And a similar test program for the other timer class, System.Threading.Timer, shows the exact same results.

在我的实际程序中,我需要以每秒精确的 50 个样本收集测量值.这应该还不需要实时系统.而且每秒获得 32 个样本而不是 50 个样本非常令人沮丧.

In my actual program, I need to collect measurements at precisely 50 samples per second. This should not yet require a real-time system. And it is very frustrating to get 32 samples per second instead of 50.

有什么想法吗?

@克里斯:你是对的,间隔似乎都是 1/64 秒左右的整数倍.顺便说一句,在事件处理程序中添加 Thread.Sleep(...) 没有任何区别.考虑到 System.Threading.Timer 使用线程池,所以这是有道理的,因此每个事件都在空闲线程上触发.

@Chris: You are right, the intervals all seem to be integer multiples of something around 1/64th second. Btw, adding a Thread.Sleep(...) in the event handler doesn't make any difference. This makes sense given that System.Threading.Timer uses the thread pool, so each event is fired on a free thread.

推荐答案

嗯,实际上我得到了高达 100 Hz 的不同数字,有一些很大的偏差,但在大多数情况下更接近请求的数字(运行 XP SP3最新的 .NET SP).

Well, I'm getting different number up to 100 Hz actually, with some big deviations, but in most cases closer to the requested number (running XP SP3 with most recent .NET SPs).

System.Timer.Timer 是使用 System.Threading.Timer 实现的,所以这解释了为什么您会看到相同的结果.我想计时器是使用某种调度算法等实现的(这是内部调用,也许查看 Rotor 2.0 可能会对此有所了解).

The System.Timer.Timer is implemented using System.Threading.Timer, so this explains why you see same results. I suppose that the timer is implemented using some kind of scheduling algorithm etc. (it's internal call, maybe looking at Rotor 2.0 might shed some light on it).

我建议使用另一个调用 Sleep 和回调的线程(或它们的组合)来实现一种计时器.虽然不确定结果.

I would suggest to implement a kind of timer using another thread (or combination thereof) calling Sleep and a callback. Not sure about the outcome though.

否则你可以看看多媒体计时器(调用).

Otherwise you might take a look at multimedia timers (PInvoke).

这篇关于C# 为什么定时器频率非常低?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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