1

現在 3 つのタイマーを持つ Windows サービスを作成しました。最初のタイマーは 15 秒ごとに起動し、2 番目のタイマーは 1 分ごとに起動します。3番目のタイマーは毎日起きています。

問題は、これらが毎回新しいスレッドを生成し、一度スレッドプールが完全に使い果たされることです.3つのスレッドを生成するだけで、それ以上新しいスレッドを生成しないことはありますか.

私のコードは次のようになります。

protected Onstart()
{
  var timer1  = new TImer();
  timer.Elapsed += Event1;
  timer1.interval = 60000;
  timer1.start();

  var timer2  = new TImer();
  timer2.Elapsed += Event2;
  timer2.interval = 60000;
  timer2.start();
}

private Event1(object,elapsedeventargs)
{
  var workerthread1 = **new thread**(workerthreadfunc1)
  workerthread1.start();
}

private Event2(object,elapsedeventargs)
{
  var workerthread2 = **new thread**(workerthreadfunc2)
  workerthread2.start();
}

ご覧のとおり、ある時点でスレッドプール内のすべてのスレッドを使い果たし、Windows サービスを突然停止する新しいスレッドを作成しています。現在、イベント ID 5000 の evet ログを停止してログしています。

4

5 に答える 5

5

問題は ThreadPool にはありません。タイマーの1つが「カチカチ」するたびに、独自のスレッドを作成しています。workerthreadfunc1 と workerthreadfunc2 が何をしているのかはわかりませんが、それらが返されない場合は、スレッドをどんどん作成し続けることになります。

System.Timers.Timer を使用している場合、Elapsed イベントは既に ThreadPool スレッドにあります。そこで希望の手術をしてみませんか?

于 2009-11-18T16:10:16.957 に答える
1

新しいスレッドを生成する代わりに、ThreadPoolを使用します。

于 2009-11-18T16:03:27.953 に答える
1

タイマーを含まないようにデザインを変更します。開始時に、3つのスレッドを作成し、workerthreadfunc1およびworkthreadfunc2で行われた作業を、最初または最後に適切な時間(15秒、1分など)のthread.sleepでループします。ループ。ループの最初にチェックを追加して、誰かがサービスを停止しようとしているかどうか、または別のサービスがすでに開始されているかどうかを確認することをお勧めします。

于 2009-11-18T16:03:59.833 に答える
1

スレッドがまだ作成されていない場合にのみ、スレッドの作成を試みることができます。クラスレベルでworkerthread1を宣言し、次のようにします。

if(workerthread1 != null)
{
      workerthread1 = new thread(workerthreadfunc1);
}
于 2009-11-18T16:04:37.210 に答える
1

@marr75 @ザック

これらはどちらも良いアドバイスですが、そうでない理由は次のとおりです。

int x = 0; //last exec timestamp(ts)
int s = 0; //15 s ts
int m = 0; //min ts
int d = 0; //day ts
while(check for event()){ //e.g. stop service etc.
   if((x - s)>15){
      //code for ever 15 s here
      s = currentTime();
   }
   if ((x - m)>60){
      //code for every min here
      m = currentTime();
   }
   if ((x - d)> 86400)(
      //code for every day here
      d = currentTime();
   }
   sleep(5000); // or wait() w/e sleeps the thread for 15s
   x = currentTime();
}

ただし、これは、SQLクエリや挿入などのより重いタスクを実行している場合、比較的軽いタスクを実行していることを前提としています。

15 秒と最小のワーカー スレッドの実行にはそれぞれ 15 秒と 1 分よりも長い時間がかかるため、オーバーフローが発生する可能性があります。これが当てはまる場合、スレッドを追加する速度が速くなり、最終的には msergeant が言おうとしていたようにオーバーフローにつながります。古いワーカー スレッドが終了したら、新しいスレッドを追加します。

于 2009-11-18T16:16:44.667 に答える