XP 中的 Diagnostics.StopWatch 时间滞后,但 Win7 中没有
ETA:使用Environment.TickCount 不会出现同样的问题。
ETA2:我应该补充一点,我实际上并没有在我的应用程序中使用 Forms.Timer - 因为这会 否定使用高频定时器。我在这里使用它来简化代码。
ETA3:我已经发布了一个解决方法作为下面的答案。
我在使用 XP 的笔记本电脑上观察到 StopWatch 类的问题,但在使用 Win7 的其他笔记本电脑上却没有观察到。这是测试代码:
Public Class FormTest
Inherits Form
Private WithEvents Timer1 As System.Windows.Forms.Timer = New System.Windows.Forms.Timer
Private sw As Stopwatch = New Stopwatch
Public Sub New()
Me.Timer1.Interval = 1
End Sub
Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
MyBase.OnClick(e)
Me.sw.Start()
Me.Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.Text = sw.ElapsedMilliseconds.ToString
Me.Update()
End Sub
End Class
在 Windows 7 上,每秒检查经过的毫秒数,我得到类似以下内容的信息: 0、1010、2030、3005 ...
在 XP 上,我得到的结果如下:0、200、306、390、512……
也就是说,相差甚远。我们不是在谈论毫秒。 这与计时器是否高分辨率无关,因为报告为真。作为 据我所知,这与处理器亲和力无关,因为我已经尝试将其设置为两个处理器中的每一个。
正如我所说,我认为这与 XP 有关,但也可能与不同的内核有关 - 然而,两台笔记本电脑都是英特尔的。
ETA: Using Environment.TickCount does not present the same problem.
ETA2: I should add that I don't actually use the Forms.Timer in my app - as this would
negate the use of a high frequency timer. I've used it here to simplify the code.
ETA3: I've published a workaround as an answer below.
I'm having problems with the StopWatch class that I'm observing on a laptop with XP but not a different laptop with Win7. Here's the test code:
Public Class FormTest
Inherits Form
Private WithEvents Timer1 As System.Windows.Forms.Timer = New System.Windows.Forms.Timer
Private sw As Stopwatch = New Stopwatch
Public Sub New()
Me.Timer1.Interval = 1
End Sub
Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
MyBase.OnClick(e)
Me.sw.Start()
Me.Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.Text = sw.ElapsedMilliseconds.ToString
Me.Update()
End Sub
End Class
On windows 7, checking the ellapsed milliseconds every second, I get something like:
0, 1010, 2030, 3005 ...
On XP, I get something like: 0, 200, 306, 390, 512, ...
That is, it is way off. We're not talking about milliseconds.
It's nothing to do with whether the timer is high resolution, as that reports as true. As
far as I know it's nothing to do with processor affinity as I've tried setting that to each of the 2 processors.
As I say, I think this is to do with XP, but it could be to do with the different cores - both laptops are, however, intel.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否在任何地方设置计时器的间隔?
在我看来,他们的跑步时间间隔不同。 Win7大概每秒都会被触发一次。 XP 看起来可以每 100 毫秒触发一次(错过了一些样本点 - 很难这么快地读取内容)。
我找不到任何有关默认计时器间隔的文档。如果它没有记录,则可能已在您的计算机之间的操作系统和 .NET 框架版本之间进行了更改。
Do you set the interval of the timer anywhere?
To me it looks like they are running with different intervals. The Win7 is roughly fired every second. The XP one looks like it could be fired every 100ms (with a few sample points missed - it's hard to read things that fast).
I can't find any documentation on the default timer interval. If it is undocumented, it could have been changed between OS and .NET framework versions between your machines.
我已经通过使用 timeGetTime 方法解决了这个问题。下面的代码是
基本上是 Diagnostics.StopWatch 类,但将 QueryPerformanceCounter 调用替换为 timeGetTime。
我还没有完全测试它*但是,从我读到的内容来看,我应该能够打电话给
TimeBeginPeriod(1) 实现与框架秒表一致的分辨率。
(*如果现在已经对其进行了全面测试并且它确实达到了毫秒精度)。
如果有人可以告诉我如何使 QueryPerformanceCounter 在 XP 上工作(如果 XP 确实是问题所在),或者检测是否存在问题,我将取消标记并将您的标记为答案。
I've solved the problem by using the timeGetTime method instead. The following code is
basically the Diagnostics.StopWatch class but with the QueryPerformanceCounter call replaced with timeGetTime.
I haven't fully tested it yet* but, from what I've read, I should be able to make a call to
TimeBeginPeriod(1) to achieve resolution in line with the framework stopwatch.
(*If have fully tested it now and it does achieve millisecond accuracy).
If anyone can tell me how to make QueryPerformanceCounter work for XP (if indeed XP is the problem), or detect if there is a problem, I'll un-mark this and mark yours as the answer.