1

我创建了一个 Windows 服务,它目前有三个计时器。第一个定时器每 15 秒唤醒一次,第二个定时器每分钟唤醒一次。第三个计时器每天都在醒来。

问题是这些每次都产生新线程,并且有一次线程池完全用完。是否只产生 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 的事件日志。

4

5 回答 5

5

您的问题不在于 ThreadPool。每次您的计时器之一“滴答”时,您都在创建自己的线程。我不知道 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 中完成的工作循环,并在线程的开始或结束时使用 thread.sleep 持续适当的时间(15 秒、1 分钟等...)环形。您可能希望在循环开始时添加一些检查,以查看是否有人试图停止服务,或者是否已经启动了另一个服务。

于 2009-11-18T16:03:59.833 回答
1

如果尚未创建线程,您可以尝试仅创建线程。在类级别声明 workerthread1 并执行以下操作:

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

@marr75 @zac

这两个都是很好的建议,但为什么不呢:

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 查询和插入或其他任务),则假设您执行的是相对较轻的任务,只是确保线程在完成后自行终止。

您可能会出现溢出,因为您的 15s 和 min 工作线程分别需要超过 15s 和 1 min 的时间来执行,如果这是真的,您将更快地添加线程,然后它们最终终止导致溢出,正如 msergeant 试图说的那样,只有如果您的旧工作线程已完成,请添加一个新线程。

于 2009-11-18T16:16:44.667 回答