为什么System.Timers.Timer.Interval的数据类型是double?
这是一个学术问题,因为我正在努力克服微软使用double作为Interval属性的数据类型的想法!
首先来自MDSN Interval是Elapsed事件之间的时间(以毫秒为单位); 我会将其解释为离散数,那么为什么要使用双? 肯定是int或long更有意义!?
Inter Interval是否支持5.768585(5.768585 ms)等值? 特别是当人们认为System.Timers.Timer无法达到亚毫秒精度时…… .NET中最准确的计时器?
对我来说似乎有些愚蠢..也许我错过了什么!
反汇编显示通过调用(int)Math.Ceiling(this.interval)
来消耗间隔,因此即使您要指定实数,它也会在使用前变为int
。 这发生在名为UpdateTimer
的方法中。
为什么? 不知道,或许规范说一次需要double
并且改变了? 最终的结果是double
并不是严格要求的,因为它最终会转换为int
并且根据文档无论如何都不能大于Int32.MaxValue
。
是的,计时器可以“支持”实数,它只是没有告诉你它默默地改变了它们。 您可以使用100.5d
初始化并运行计时器,将其变为101
。
是的,它有点愚蠢:4个浪费的字节,潜在的隐式转换,转换调用,显式转换,如果它们只是使用int
它们都是不必要的。
在这里使用double的原因是尝试提供足够的准确性。
详细说明:系统中断时间片由ActualResolution给出,由NtQueryTimerResolution()
返回。 NtQueryTimerResolution由本机Windows NT库NTDLL.DLL导出。 系统时间增量由TimeIncrement给出,由GetSystemTimeAdjustment()
返回。
这两个值决定了系统计时器的行为。 它们是整数值,表示100 ns单位。 但是,这对于某些硬件来说已经不够了。 在某些系统上, ActualResolution返回9766,对应于0.9766 ms。 但实际上这些系统每秒运行1024次中断(通过适当设置多媒体接口进行调整)。 每秒1024次中断将导致中断周期为0.9765625 ms。 这是太高的细节,它达到100 ps的状态,因此不能保持标准的ActualResolution格式。
因此,已经决定将这些时间参数加倍。 但是:这并不意味着支持/使用所有可能的值。 无论如何 , TimeIncrement给出的粒度将持续存在。
在处理定时器时,始终建议查看所涉及参数的粒度。
回到你的问题: Can Interval support values like 5.768585 (ms) ?
不 ,我以上作为例子的系统不能。
但它可以支持5.859375(ms)!
具有不同硬件的其他系统可以支持其他数字。
因此,在这里引入双重的想法并不是一个愚蠢的想法,实际上是有道理的。 花费另外4个字节来获得最终的结果是一项很好的投资。
我在这里总结了一些关于Windows时间问题的更多细节。