0

我目前正在尝试编写一个每秒运行 100 次完全相同的代码的应用程序。我已经使用 .NET 框架的内置计时器进行了一些测试。我测试了 System.Threading.Timer 类、System.Windows.Forms.Timer 类和 System.Timers.Timer 类。对于我正在尝试做的事情,它们似乎都不够准确。我发现了 PerformanceCounters 并且目前正在尝试在我的应用程序中实现它。但是,我的程序在空闲时占用了 CPU 的整个内核时遇到了一些麻烦。我只需要它每秒激活 100 次。我的循环如下所示:

long nextTick, nextMeasure;

QueryPerformanceCounter(out start);
nextTick = start + countsPerTick;
nextMeasure = start + performanceFrequency;

long currentCount;
while (true)
{
    QueryPerformanceCounter(out currentCount);

    if (currentCount >= nextMeasure)
    {
        Debug.Print("Ticks this second: " + tickCount);
        tickCount = 0;
        nextMeasure += performanceFrequency;
    }

    if (currentCount >= nextTick)
    {
        Calculations();
        tickCount++;

        nextTick += countsPerTick;
    }
}

如您所见,大多数情况下,程序将通过不断地运行 while 循环来等待再次运行 Calculations()。有没有办法阻止这种情况发生?我不想降低运行我的程序的计算机的速度。不幸的是,System.Thread.Thread.Sleep 也很“不准确”,但如果没有其他解决方案,我可以使用它。

我基本上要问的是:有没有办法让无限循环减少 CPU 密集度?有没有其他方法可以准确地等待特定的时间?

4

2 回答 2

2

我相信您知道,Windows 不是实时操作系统,因此永远无法保证您的代码会随心所欲地运行。

话虽如此,就让步给其他线程而言,最有效的可能是使用 Thread.Sleep() 作为计时器。如果您想要比默认值更高的精度,您可以发出一个 timeBeginPeriod ,其所需的分辨率低至一毫秒。该函数必须是从 winmm.dll 导入的 DLLImported。

于 2012-06-08T00:31:39.473 回答
1

timeBeginPeriod(1)与普通计时器一起使用或Thread.Sleep应该可以正常工作。

请注意,这具有全局影响。有人声称它会增加功耗,因为它会强制 Windows 计时器更频繁地运行,从而缩短 CPU 睡眠时间。这意味着您通常应该避免它。但是,如果您需要高度准确的计时,它肯定是比忙碌等待更好的选择。

于 2012-06-08T00:50:09.393 回答