2012-11-15 16 views
19

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

答えて

22

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

これは、(イベントにSet()を呼び出すことにより)必要なときに、それはあなたの無限の「ブロック」から出るにクリーンな方法を提供することを除いて、いつまでも寝てと同様の効果を持つことになります。

while(true)を使用すると、CPUサイクルが消費されるため、避けるべきことは間違いありません。

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

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

+0

私は実際にそれがすべて終了することを望んでいませんが、退出する方法を持っていることを望む人がいる場合に私はあなたの答えを受け入れます。 – Lunyx

+0

@ダニエルそれはあなたが特定の時点で望む何かではないにしても、あなたのプログラムがシャットダウン*するためのきれいな方法を持っていることは素晴らしいことです;)私はまだ睡眠以上にこのアプローチを使用して、個人的に –

+0

プログラムが終了する唯一の時間がマシンの再起動時である場合、ManualResetEventの使用方法はThread.Sleep()とどのように異なるでしょうか? – Lunyx

4

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

スレッドがスリープしている場合は、何もしないでください。

あなたのスレッドはThread.Sleepに入った時点でブロックされているので、あなたがリソースにしたいことは何でも公正なゲームです。よりスマートな方法でsleep()作品ながら

+0

おかげで、私は私がやって達成しようとして人々に推奨されているwhileループを見てきましたし、それはそれについて移動するための正しい方法だった場合、私はわかりませんでした。 – Lunyx

2

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

sleep()に電話すると、CPUは他の作業を行うことができます。

これがsleep()が便利な理由の1つです。

便利なリンク - Be careful when using Sleep

3

私は

Thread.Sleep(Timeout.Infinite); 

が実際にOSネイティブのスケジューラの助けを借りて、スリープ状態にスレッドを取得wheareasスレッドは、停止したことがないので、コール

while (true) { ... } 

は、計算集約的であると思います。そしてスレッドが実際に停止するので、計算量が少なくて済むと思います。

+2

あなたの答えには不確かさがあるようです... "私は思う"、 "私が思う"など –

+0

私は答えについて確信していましたが、私はちょうど私が "考えている" "予防のために。 :) – leoismyname

関連する問題