可以在.NET秒表类是这还了得? [英] Can the .NET Stopwatch class be THIS terrible?

查看:167
本文介绍了可以在.NET秒表类是这还了得?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做,需要一些pretty的紧张时刻的应用程序,秒表类是完美的解决方案。不过,我有时会发现,一个小平板电脑上运行时,秒表值分别为路要走。我加了一些调试打印监测秒表的价值每200 毫秒左右:

I'm making an application that needs some pretty tight timing, and the Stopwatch class is the perfect solution. However, I noticed sometimes, when running on a small panel PC, the Stopwatch values were way off. I added some debug printouts that monitor the value of the stopwatch every 200 ms or so:

0:00:197
  0:00:502
  0:00:702
  ...
   0:03:356
  0:12:93

  〇点13分21秒
  0:13:421
  ......

0:00:197
0:00:502
0:00:702
...
0:03:356
0:12:93

0:13:21
0:13:421
...

怎么会可能来自〜3秒〜13秒跳?我现在看到的底层函数QueryPerformanceCounter的()是越野车(的 当心QueryPerformanceCounter的()的 的),但我得到的感觉,别的东西是怎么回事。

How could it possibly jump from ~3 seconds to ~13 seconds? I now see that the underlying function QueryPerformanceCounter() is buggy (Beware of QueryPerformanceCounter()), but I get the sense that something else is going on here.

任何有识之士为AP preciated。

Any insight is appreciated.

更新:

下面是我的code更详细一点:这是pretty的简单。这是创建一个新的秒表对象上启动一个WPF应用程序,然后通过踢它关闭的start()。然后创建一个 DispatcherTimer ,像这样:

Here's a little more detail on my code: it's pretty straightforward. It's a WPF application that creates a new Stopwatch object on startup, and then kicks it off via Start(). I then create a DispatcherTimer, like so:

displayTimer = new DispatcherTimer(); 
displayTimer.Tick += display_Tick; 
displayTimer.Interval = DISPLAY_INTERVAL_TIMESPAN; 

在这里的时间跨度为200 毫秒。我调试code简单地打印出秒表对象每次 dispatchTimer 蜱的价值。

where the timespan is 200 ms. My debug code simply prints out the value of the Stopwatch object every time the dispatchTimer ticks.

一个调试日志是 dl.dropbox.com/u/7999907/hburg.txt 。数据每行的第一位是通过 DateTime.UtcNow 当前的日期/时间。时间一路权是通过 Stopwatch.Elapsed 的值。你可以看到秒表跳,但日期时间没有。

A debug log is at dl.dropbox.com/u/7999907/hburg.txt. The first bit of data on each line is the current date/time via DateTime.UtcNow. The time all the way to the right is the value via Stopwatch.Elapsed. You can see how the stopwatch jumps, but the DateTime doesn't.

UPDATE2:

一个有趣的Microsoft支持文章的 性能计数器值可能会意外地跃进

A fun Microsoft support article is Performance counter value may unexpectedly leap forward.

推荐答案

更新(看到你的日志后)

正如你已经提到的,秒表类使用<一个href="http://msdn.microsoft.com/en-us/library/ms644904%28VS.85%29.aspx"><$c$c>QueryPerformanceCounter功能下面。在说明的部分MSDN说:

As you already mentioned, the Stopwatch class uses the QueryPerformanceCounter function underneath. In the Remarks section MSDN says:

在多处理器计算机<​​/ em>的,它不应该的问题该处理器被调用。然而, 你可以在不同的处理器不同的结果由于在基本输入/输出系统(BIOS)或硬件抽象层(HAL)的错误。要为指定线程处理器的亲和力,使用SetThreadAffinityMask功能。

On a multiprocessor computer, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL). To specify processor affinity for a thread, use the SetThreadAffinityMask function.

当你正在使用分派, QueryPerformanceCounter的可能无法在同一CPU上每次您查询所经过的时间的时间执行。

As you are using the Dispatcher, QueryPerformanceCounter might not be executed on the same CPU every time that you query the elapsed time.

您都不可能检查MSDN中提到的问题是通过指定的处理器亲和力的过程中,如您的问题的原因通过调用使用可执行启动命令。 10秒似乎是CPU之间的一个很大的滞后给我,但文档是很模糊多大的差异而定。以下命令将您的应用程序绑定到的第一个CPU:

You can possibly check if the issue mentioned in MSDN is the reason for your problem by specifying a processor affinity for your process, e.g. by calling your executable using the start command. 10 seconds seems like a big lag between CPUs to me, but the documentation is very vague on how big the difference may be. The following command will bind your application to the first CPU:

> start.exe /AFFINITY 1 program.exe

如果这应该解决的问题,你可能想看看该建议的解决办法,即查询秒表<前调用 SetThreadAffinityMask 功能/ code>对象。

If this should solve the issue you might want to have a look at the suggested workaround, i.e. calling the SetThreadAffinityMask function before querying the Stopwatch object.

您的评论说,您正在使用WPF DispatcherTimer 。该<一href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer.aspx">documentation那类状态:

Your comment said that you are using a WPF DispatcherTimer. The documentation of that class states:

定时器不能保证当时间间隔恰好出现执行 的,但一定的时间间隔发生之前不会执行。这是因为DispatcherTimer操作被放置在分派队列像其他操作。当DispatcherTimer操作执行是依赖于队列优先级的其他工作。

Timers are not guaranteed to execute exactly when the time interval occurs, but they are guaranteed to not execute before the time interval occurs. This is because DispatcherTimer operations are placed on the Dispatcher queue like other operations. When the DispatcherTimer operation executes is dependent on the other jobs in the queue and their priorities.

这意味着,计时器事件可能到达时延迟,特别是当调度是忙于其他任务。你把其他的东西,在调度队列中,将prevent事件从早期的触发?

This means that the timer event may arrive delayed, especially if the dispatcher is busy with other tasks. Did you place other things in the dispatcher queue that will prevent the event from triggering earlier?

这篇关于可以在.NET秒表类是这还了得?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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