1

1つ以上のバックグラウンドスレッドをホストできるWindowsサービスがあります。各バックグラウンドスレッドは、ポーリングループを開始して作業をチェックします。私はループを実装するために次のパターンを使用しています:

new Thread(DoWork).Start();

private void DoWork()
{
    while(keepRunning)
    {
        Console.WriteLine(DateTime.Now);
        Thread.Sleep(1000);
    }
}

CPUの消費量が少ない代替品を見つけようとしています。再帰的な方法でタイマーを使用してポーリングループを実現することができました。

var timer = new Timer(WakeUp, null, Timeout.Infinite, 1000)
timer.Change(0, 1000);

private void WakeUp(object state)
{
    lock (locker)
        Monitor.Pulse(locker);
}

private void DoWork()
{
    lock (locker)
    {
        if (!keepRunning) return;
        Console.WriteLine(DateTime.Now);
        Monitor.Wait(locker);
        DoWork();
    }
}

あるパターンを他のパターンよりも使用することに利点はありますか?バックグラウンドスレッドでポーリングループを設定するためのより良いパターンはありますか?

4

1 に答える 1

3

CPUの消費量が少ない代替品を見つけようとしています。

現在、実際にかなりの量のCPUを消費しているという証拠はありますか?同じような時間に起きて競合しているスレッドがたくさんない限り、私はThread.Sleepかなり効率的だと思います。

再帰的なDoWork方法ははるかに悪いです-末尾呼び出しが最適化されていない限り、最終的にはスタックオーバーフローで爆発します。少なくともループしないのはなぜですか?そもそもタイマースレッドで実際の作業をしてみませんか?

keepRunningタスクごとに1つのスレッドが本当に必要で、1秒に1回作業を行う場合は、最初のコードで問題ありません(ただし、フィールドだけの場合は、新しい値を「確認」する必要があります。使用を検討してInterlockedください)。ただし、理想的には、これらのスレッドをまったく使用しないでください。適切なタイマーを使用して、1秒に1回作業をスケジュールし、スレッドプールに処理させてください。

于 2012-10-22T22:23:40.877 に答える