我创build了一个目前有三个计时器的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(); }
所以你可以看到它正在创build新的线程,它将在线程池中的所有线程用完,并突然停止Windows服务。 目前正在停止和劫持事件ID为5000的evet日志。
你的问题不在于ThreadPool。 每当你的一个定时器“打勾”时,你就创建了自己的线程。 我不知道workerthreadfunc1和workerthreadfunc2在做什么,但是如果它们没有返回,你将继续创建越来越多的线程。
如果您正在使用System.Timers.Timer比Elapsed事件已经在一个ThreadPool线程上。 为什么不在那里执行你想要的操作?
而不是产生新的线程,使用ThreadPool 。
我会改变设计,不包括任何计时器。 在开始的时候,创建3个线程,然后在workerthreadfunc1和workthreadfunc2中使用一个thread.sleep进行一个循环,时间为(15秒,1分钟等等)的开始或结束循环。 您可能希望在循环的开始处添加一些检查,以查看是否有人试图停止该服务,或者如果另一个已经启动。
您可以尝试只创建线程,如果它尚未被创建。 在班级宣布workerthread1并执行如下操作:
if(workerthread1 != null) { workerthread1 = new thread(workerthreadfunc1); }
@ 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()){ //eg 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和15min而被溢出,如果这是真的,你将会加快线程速度,最终导致溢出,因为msergeant试图说如果您的旧工作线程完成,请添加一个新线程。