32

バックグラウンド ワーカーを使用して DLL をポーリングし、次のようなステータスを取得するメソッドがあります。

var timeout = DateTime.Now.AddSeconds(3);
while (System.Status != Status.Complete  // our status is not complete
       && DateTime.Now < timeout         // have not timed out
       && !_Worker.CancellationPending)  // backgroundworker has not been canceled
{
    //Thread.Yield();
    //Thread.SpinWait(1);
    //Thread.Sleep(1);
}

CPU % を見るとyield()spinwait()PC でアプリが最大 50% まで起動します。私の CPU使用Sleep(1)率は 6% のままです。を選択するように言われThread.Yield()ましたが、CPU % のスパイクが気になります。このようなもののベストプラクティスは何ですか?

4

1 に答える 1

32

Thread.Yieldは、現在のスレッドを中断して、他のスレッドが作業できるようにします。ただし、実行する作業がない場合、スレッドはすぐに再スケジュールされ、ポーリングを継続するため、1 コアの使用率は 100% になります。

呼び出し元のスレッドが、現在のプロセッサで実行する準備ができている別のスレッドに実行を譲るようにします。オペレーティング システムは、譲るスレッドを選択します。

Thread.Sleepは、スリープ時間が経過した後にスレッドを再度実行するようにスケジュールするため、CPU 使用率が大幅に低下します。

指定されたミリ秒数の間、現在のスレッドをブロックします。

どちらかを選択するとThread.Sleep、タスクにより適したものになります。Threading.Timerただし、よりエレガントなソリューションになるという@Bryanのコメントには同意します。

于 2012-07-14T04:12:34.227 に答える