1

Windows サービスを作成するように言われた方法は次のとおりです。

Thread serviceThread = new Thread(new Thread(runProc())
Boolean isRunning = true;

if (_isRunning)
   {
      serviceThread.Start();
   }else
      close and log service

void runProc()
{
   while(_isRunning)
   {
      //Service tasks
   }

   _isRunning = false;
}

これはこれまでのところうまくいきましたが、一度に最大 2 時間までの大きな休憩を含むサービスを作成する必要があります。また、タイマーの使用を開始したため、無限ループで実行されている runProc() を何度も何度も停止する以外に何も行われていません。

私の質問は、その while(_isRunning) 無限ループに Thread.Sleep(big number) を入れるのは悪い習慣だと読んだことがありますが、これは本当ですか? この場合、絶え間なく実行され、大量のリソースを使用するループを回避するにはどうすればよいですか? 現在、ループで文字通り何も行われていません。すべてタイマーの tickevent で処理されます。ループがある唯一の理由は、runProc の終了を停止することです。

どうもありがとうございました。

4

2 に答える 2

2

Thread.Sleep(簡単に)中断できないため悪い1 .

ManualResetEvent私は通常、または類似のものを使用することを好みます。

class abc {
  Thread serviceThread = new Thread(new Thread(runProc())
  ManualResetEvent abort = new ManualResetEvent(false);

  void Start(){
      serviceThread.Start();
  }
  void Stop(){
     abort.Set();
     serviceThread.Join();
  }
  void runProc()
  {
     while(!abort.WaitOne(delay))
     {
      //Service tasks
     }
  }
}

すばらしいコード サンプルではなく、要点を理解していただければ幸いです。

delay必要に応じて大きくすることも小さくすることもできます (ループごとに任意に再計算できます)。このWaitOne呼び出しは、このスレッドの進行をdelayミリ秒遅らせるか、Stop呼び出された場合はループをすぐに終了させます。


1以下のコメントから私の立場を要約すると、コードの他のさまざまな場所で関連する例外を導入できるという失敗を (多かれ少なかれ) 共有するThread.Abortような鈍いツールによってのみ中断することができます。スレッドが実際に呼び出し内にあることを保証できる場合は、後者で問題ないかもしれませんが、そのような保証を行うことができる場合は、通常、より鈍くないスレッド間通信メカニズムを使用するように手配することもできます。この回答で提案しました。Thread.InterruptThread.Sleep

于 2013-10-28T15:10:24.933 に答える
0

私は常に、タイマーではなく、メインの無限ループを使用してサービスを作成してきました。ループ内で、実行する作業があるかどうかを確認し、ある場合は作業を行い、ない場合は を呼び出しますThread.Sleep()。つまり、実行する作業がある限り、ループは反復を続け、可能な限り高速に実行されます。作業のキューが「枯渇」すると、少し (数秒または数分) スリープ状態になり、より多くの作業が利用可能になります。

これは、1 日 (および夜間) を通じて新しい作業が絶え間なく行われるサーバー上のバックエンド ジョブでは、常に非常にうまく機能します。仕事のない期間が長い場合、サービスは何度も起動してチェックしてからスリープ状態に戻ります。あなたはそれが好きかどうかかもしれません。チェックが迅速である限り、問題にはなりません。別の方法は、スケジュールされたタスク (またはデータベース ジョブ) を使用して、1 日を通して特定の時間に作業が完了することを確認することです。場合によっては、それがより良いアプローチです。

于 2013-10-28T15:11:52.753 に答える