0

私は現在、同じコードを1秒間に正確に100回実行するアプリケーションを作成しようとしています。.NETFrameworkの組み込みタイマーを使用していくつかのテストを行いました。System.Threading.Timerクラス、System.Windows.Forms.Timerクラス、およびSystem.Timers.Timerクラスをテストしました。それらのどれも私がやろうとしていることに対して十分に正確ではないようです。PerformanceCountersについて知り、現在、アプリケーションにそのようなものを実装しようとしています。ただし、アイドリング時にプログラムがCPUのコア全体を占めることに少し問題があります。1秒間に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はリアルタイムのO / Sではないため、コードが必要な頻度で実行される保証はありません。

そうは言っても、他のスレッドに譲るという点で最も効率的なのは、おそらく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 に答える