web-dev-qa-db-ja.com

Is Thread.Sleep(Timeout.Infinite); while(true){}よりも効率的ですか?

イベントをリッスンしている間、常に開いておきたいコンソールアプリケーションがあります。私はThread.Sleep(Timeout.Infinite);while (true) { }をテストしましたが、どちらもコンソールアプリケーションを開いたままイベントを発生させることができます。他に使用すべきものはありますか?スレッドがスリープ状態の場合、クラスのスコープで宣言された静的コレクションの変更など、私がしてはいけないことはありますか?

26
Lunyx

ManualResetEvent(またはその他のWaitHandle)を使用して、 ManualResetEvent.WaitOne を呼び出すことをお勧めします。

これは、永久にスリープするのと同様の効果がありますが、必要なときに無限ブロックからexitへのクリーンな方法を提供します(- Set() イベントの場合)。

while(true)を使用するとCPUサイクルが消費されるため、これは間違いなく避けてください。

クラスのスコープで宣言された静的コレクションを変更するなど、私がしてはいけないことはありますか?

一般的には違います。スレッドがブロックされるため、共有データの使用に同期の問題はありません(コレクション内のアイテムに、適切な同期コンテキストを持つスレッドで使用する必要があるユーザーインターフェイス要素などの特定の要件がない場合)。 。)

28
Reed Copsey

while(true)...とは異なり、Thread.SleepはCPUサイクルを使用しないため、この意味で、スリープはより効率的です。一般に、 spinlocks の外で Busy Waiting を使用することは強くお勧めしません。

スレッドがスリープしている場合、私がしてはいけないことはありますか?

Thread.Sleepへのエントリ時にスレッドがブロックされるため、そのリソースに対して実行したいことは何でも公正なゲームです。

4
dasblinkenlight

電話だと思う

while (true) { ... } 

スレッドは停止しないため、計算集約的であり、

Thread.Sleep(Timeout.Infinite);

実際には、OSネイティブスケジューラの助けを借りてスレッドをスリープ状態にします。そして、スレッドは実際に停止するので、計算の負荷が軽減されると思います。

4
leoismyname

はいwhile(true)はCPUを消費しますが、sleep()はよりスマートに機能します:sleep()関数は、現在の実行コンテキストをスリープ状態にします。これは、syscallを呼び出して、カーネルスリープ関数を呼び出し、
(a)ウェイクアップタイマーを設定する
(b)現在のプロセスをスリープ状態としてマークします
(c)ウェイクアップタイマーが起動するか、割り込みが発生するまで待機します

sleep()を呼び出すと、CPUは他の処理を実行できます。

これが、sleep()が役立つ理由の1つです。

便利なリンク- スリープを使用するときは注意してください

2
Grijesh Chauhan

Thread.Sleepメソッドを呼び出すと、現在のスレッドがミリ秒数またはメソッドに渡された時間間隔で直ちにブロックされ、残りのタイムスライスが別のスレッドに渡されます。

https://msdn.Microsoft.com/en-us/library/tttdef8x(v = vs.110).aspx

0
Alberto

C#7.1以降、Mainメソッドを非同期にすることができます。つまり、busy-waitやthread-locking sleepingを使用する代わりに、MainメソッドをTaskとして非同期に中断できます。このように実行されたスレッドMainはロックされません。また、Cts.Cancel();を使用すると、メインタスクを簡単に解放してアプリケーションを終了できます。

readonly CancellationTokenSource Cts = new CancellationTokenSource();
static async Task Main(string[] args)
{
    /* your code here */

    await Task.Delay(Timeout.Infinite, Cts.Token);
}
0
Vinigas