这是一个学术问题,因为我正在努力克服微软使用double作为Interval属性的数据类型的想法!
首先来自MDSN Interval是Elapsed事件之间的时间(以毫秒为单位);我会将其解释为离散数,那么为什么要使用双?肯定是int或long更有意义!?
Interval可以支持5.768585(5.768585 ms)等值吗?特别是当人们认为System.Timers.Timer无法达到亚毫秒精度时...... Most accurate timer in .NET?
对我来说似乎有些愚蠢......也许我错过了什么!
答案 0 :(得分:12)
反汇编显示通过调用(int)Math.Ceiling(this.interval)
消耗了间隔,因此即使您要指定实数,也会在使用前将其转换为int
。这发生在名为UpdateTimer
的方法中。
为什么呢?不知道,也许规范说一时需要double
而且这个改变了吗?最终结果是double
并非严格要求,因为它最终会转换为int
,并且根据文档无法大于Int32.MaxValue
。
是的,计时器可以“支持”实数,它只是没有告诉你它默默地改变了它们。您可以使用100.5d
初始化并运行计时器,并将其转换为101
。
是的,它有点愚蠢:4个浪费的字节,潜在的隐式转换,转换调用,显式转换,如果他们刚刚使用int
就不用了。
答案 1 :(得分:3)
在这里使用double的原因是尝试提供足够的准确性。
详细说明:系统中断时间片由{em> ActualResolution 给出,由NtQueryTimerResolution()
返回。 NtQueryTimerResolution由本机Windows NT库NTDLL.DLL导出。系统时间增量由{em> 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时间问题的详细信息here。