C# 线程池正在被windows服务问题使用
我创建了一个windows服务,目前有三个计时器。第一个计时器每15秒叫醒一次,第二个计时器每分钟叫醒一次,第三个计时器每天叫醒一次 问题是,这些线程每次都会产生新线程,而且有一次线程池完全用完。有没有可能只产生3个线程而不产生更多的新线程 我的代码如下所示: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
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。但看起来它根本没有捕捉到异常。