Windows サービスの場合、ウェイトスピンとタイマーのどちらが優れていますか?
-
11-09-2019 - |
質問
Windows サービスのタイマーに関するこの質問 考えさせられました:
Windows サービスがあり、それを待機しているとします (実際にそうしています)。 待機ハンドル そして目覚めると、以下のフローチャートで示したように待機スピンに入ります。
ウェイトスピン図 http://www.86th.org/waitspin.jpg
タイマーを使用する方が良いかどうか興味があります。 ウェイトスピンループ (スピン待機と呼ばれることもあります)。正直に言うと、私は自分のいじり以外にタイマーを使用したことがありません。
大きな違いがあり、タイマーを使用する利点が素晴らしい場合を除いて、切り替える予定はありません。しかし、私はこのプロジェクトの将来の発展に関して、一方と他方についての人々の考えに非常に興味があります。
これをwikiにするべきかどうか教えてください
解決
私はあなたのタイマーのうちのいずれかの利益を得て表示されません。あなたは、本質的にあなたの睡眠の呼び出しで、とにかくタイマとして動作している、と睡眠がタイムスライスを生成するので、あなたは、帯域幅を独り占めされていません。明示的なタイマーウェイクアップ持って、あなただけのコードを複雑にしようとしている呼び出します。
私は一般的に寝ていないものとして、スピン待ちを考えるので、私は本当に、あなたがスピン待ちをしているとは言えないでしょう。それはちょうど、外出先の信号を待っているすべてのそれのプロセッサ時間を燃やします。
他のヒント
スレッドをスリーピング、タイムアウトでハンドルに待機している基本的にカバーの下に同じものです。私はタイマーは、基本的にどちらか、そこに、あまりないの違いを睡眠を使用して実装されていることを推測します。言い換えれば、あなたは、単一のループでタイムアウトでハンドルを待っていると、待ち時間は(データが使用可能か、タイムアウト)にリリースされた理由を確認するためにチェックするのではなく、別の待機とスリープのループを実装することで、あなたのコードを簡素化することができます。独立したループよりも若干効率的ます。
理想的には、あなたはすべての睡眠を使用していないだろうと単純に正しく消費コードは、イベントソースがなくなったときに処理するために、長めのタイムアウトで、待機しているイベントを発生させるために、データ生成コードに依存します。
イベントは常に場合に通知されますので、その場合にポーリングする必要が - データは、ソケットまたは他の入力デバイスのように、外部にある場合は、は、その後、ハンドルは、一般的に、データが利用可能になるのを待つことができないように設定することができますデータは、消費の準備ができてます。
糸を使用しております。これらはタイマーのように機能するだけでなく、スレッドがスリープしている間に他の操作を実行するためのハンドルも提供します。
それは本当にあなたの要件に依存すると思います:
- タスクを実行する 毎 5 分 (例: 12:00、12:05、12:10、...)
- 現在のタスクが完了したら、次のタスクを実行します 後 5分。
Timer と Thread.Sleep はどちらも実行できますが、ケース 1 では Timer が簡単に見え、ケース 2 では Thread.Sleep が簡単に見えるようです。
実際、私は同様の質問に対して、より長いコメント (ケース 1 に関する考慮事項を含む) を投稿しました (Windows サービスのスケジュールされた実行).
ポーリングが悪い、とほとんど常に回避です。時折、些細なもののためにそれを回避するために必要な複雑未満悪います。
どのようなソースあなたのためにポーリングされている「データを持っています?」あなたがハンドル待ちのいくつかの種類に変わることができない?
また、時間のいずれか、かなりの量のために(サービスなど)の深刻なコードでSleep()
ません。あなただけが行うことができます遮断することはハンドルのリストは、それがプロセスをシャットダウンする時が来たときに発生するイベントが含まれてWaitFor[Single|Multiple]Objects(...)
です。どこでも検索あなたがSleep(millisec)
を呼び出し、WaitForSingleObjects(g_shutdownEvent, millisec)
と交換しています。
レイモンド・チェンが説明するように、 "うん、何でも。"あなたが取得する方法を考え出すことができない場合のが通知のデータの準備ができているとき - 。その後、あなたのSOL