Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 线程池正在被windows服务问题使用_C#_Windows_Multithreading_Threadpool - Fatal编程技术网

C# 线程池正在被windows服务问题使用

C# 线程池正在被windows服务问题使用,c#,windows,multithreading,threadpool,C#,Windows,Multithreading,Threadpool,我创建了一个windows服务,目前有三个计时器。第一个计时器每15秒叫醒一次,第二个计时器每分钟叫醒一次,第三个计时器每天叫醒一次 问题是,这些线程每次都会产生新线程,而且有一次线程池完全用完。有没有可能只产生3个线程而不产生更多的新线程 我的代码如下所示: protected Onstart() { var timer1 = new TImer(); timer.Elapsed += Event1; timer1.interval = 60000; timer1.start

我创建了一个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();
}

因此,正如您所看到的,它正在创建新线程,这将在某个时候耗尽threadpool中的所有线程,并突然停止windows服务。当前,它正在停止并删除事件ID为5000的evet日志。

使用。

而不是生成新线程,使用。

我将更改设计,使其不包含任何计时器。开始时,创建3个线程,并在workerthreadfunc1和workthreadfunc2中使用thread.sleep循环完成相应的工作15秒1分钟,以此类推。。。在循环的开始或结束处。您可能希望在循环开始时添加一些检查,以查看是否有人试图停止服务,或者是否有另一个服务已经启动。

我将更改设计,使其不包含任何计时器。开始时,创建3个线程,并在workerthreadfunc1和workthreadfunc2中使用thread.sleep循环完成相应的工作15秒1分钟,以此类推。。。在循环的开始或结束处。您可能希望在循环的开头添加一些检查,以查看是否有人试图停止服务,或者是否有另一个服务已经启动。

只有在尚未创建线程时,才可以尝试创建线程。在类级别声明workerthread1并执行以下操作:

if(workerthread1 != null)
{
      workerthread1 = new thread(workerthreadfunc1);
}

如果尚未创建线程,则只能尝试创建该线程。在类级别声明workerthread1并执行以下操作:

if(workerthread1 != null)
{
      workerthread1 = new thread(workerthreadfunc1);
}

您的问题不在于线程池。每次一个计时器滴答作响时,您都在创建自己的线程。我不知道workerthreadfunc1和workerthreadfunc2在做什么,但如果它们不返回,您将继续创建越来越多的线程


如果您使用的是System.Timers.Timer,则线程池线程上已存在已用事件。为什么不在那里执行所需的操作?

您的问题不在于线程池。每次一个计时器滴答作响时,您都在创建自己的线程。我不知道workerthreadfunc1和workerthreadfunc2在做什么,但如果它们不返回,您将继续创建越来越多的线程

如果您使用的是System.Timers.Timer,则线程池线程上已存在已用事件。为什么不在那里执行所需的操作?

@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分钟,如果这是真的,则添加线程的速度将加快,然后它们将终止,最终导致溢出,正如MSergient试图说的,只有在旧工作线程完成时才添加新线程。

@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分钟,如果这是真的,那么您将更快地添加线程,然后它们终止,最终导致溢出,正如MSergient所说,只有在旧的辅助线程完成后才能添加新线程。

如果您告诉我们或向我们展示workerthreadfuncN的功能,可能会更清楚。看起来你每15秒、每分钟、每一天都有一些工作要做。至于日常工作,这可能更好地通过某种任务调度器/cron作业来处理。我的回答将基于这样一个假设,即这是你的目标。所以我使用了这个。ThreadPool.QueueUserWorkItemnew WaitCallbackWorkerThreadFunction1;我想有人建议processtimerevent已经在一个线程上了。因此,我一直牢记这一点,并将在使用threadpool的解决方案失败时实施如果您告诉我们或向我们展示workerthreadfuncN的功能,可能会更清楚。看起来你每15秒、每分钟、每一天都有一些工作要做。至于日常工作,这可能更好地通过某种任务调度器/cron作业来处理。我的回答将基于这样一个假设,即这是你的目标。所以我使用了这个。ThreadPool.QueueUserWorkItemnew WaitCallbackWorkerT
功能1;我想有人建议processtimerevent已经在一个线程上了。因此,我一直牢记这一点,并将在使用threadpool的解决方案失败时实施这段代码不起作用,workerthread1还没有被实例化,他可以让它成为任何类/模块的变量,但是,对不起。在提交之前应该再读一次:代码不起作用,workerthread1还没有被实例化,他可以将它作为任何类/模块的变量,但是,抱歉。在提交:Thnx以获取建议之前,我应该再读一次:我希望在使用threadpool之后,服务不会再次停止:@alice:正如我所说的,您在线程池的线程中接收到经过的事件,因此您不需要为线程池排队另一个工作项。但我首先要检查线程函数是否有问题。它们似乎永远不会返回。我目前正在每个辅助线程函数中使用try和catch。但是看起来它根本没有捕捉到异常。Thnx作为建议,我希望在使用threadpool之后,服务不会再次停止:@alice:正如我所说的,您在线程池的线程中接收到经过的事件,因此您不需要为该池排队另一个工作项。但我首先要检查线程函数是否有问题。它们似乎永远不会返回。我目前正在每个辅助线程函数中使用try和catch。但看起来它根本没有捕捉到异常。