线程池被Windows服务使用问题
我创建了一个 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 的 evet 日志。
I have created a windows service which is currently having three timers. First timer is waking up every 15 sec, second timer is waking every min. and the third timer is waking everyday.
THe problem is these are spawning new threads every time and one time the threadpool gets used up completely.Is ther any to just spawn 3 threads and not spawn any more new threads.
My code looks something like this:
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();
}
So as you can see it is creating new threads which will use up all the threads in threadpool at some point and stops the windows service abruptly. Currently it is stopping and loogging a evet log with event ID 5000.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您的问题不在于线程池。每次计时器之一“滴答”时,您都会创建自己的线程。我不知道workerthreadfunc1和workerthreadfunc2在做什么,但如果它们没有返回,那么您将继续创建越来越多的线程。
如果您使用 System.Timers.Timer,则 Elapsed 事件已经在 ThreadPool 线程上。为什么不在那里执行您想要的操作呢?
Your problem is not with the ThreadPool. you're creating your own threads each time one of your timers "ticks". I don't know what workerthreadfunc1 and workerthreadfunc2 are doing but if they don't return than you'll keep creating more and more threads.
If you are using System.Timers.Timer than the Elapsed event is already on a ThreadPool thread. why not perform your desired operation there?
不要生成新线程,而是使用 ThreadPool 。
Instead of spawning new threads, use the ThreadPool.
我会更改设计以不包含任何计时器。启动时,创建 3 个线程,并在workthreadfunc1 和 workthreadfunc2 中完成的工作上放置一个循环,并在开始或结束时使用 thread.sleep 适当的时间(15 秒、1 分钟等...)环形。您可能需要在循环开始时添加一些检查,以查看是否有人试图停止该服务,或者另一个服务是否已经启动。
I would change the design to not include any timers. On start, create the 3 threads, and put a loop around the work done in workerthreadfunc1 and workthreadfunc2 with a thread.sleep for the appropriate amount of time (15 seconds, 1 minute, etc...) at the beginning or end of the loop. You might want to add some check at the beginning of the loop to see if someone is trying to stop the service, or if another one has already started.
如果尚未创建线程,您可以尝试仅创建该线程。在类级别声明workerthread1并执行以下操作:
You could try only creating the thread if it hasn't already been created. Declare workerthread1 at the class level and do something like:
@marr75
@zac
这两个都是很好的建议,但为什么不呢:
但这假设你正在做一个相对较轻的任务
如果你正在执行一项较繁重的任务,例如 SQL 查询和插入或其他任务,请确保线程在完成后自行终止。
您可能会遇到溢出,因为您的 15 秒和分钟工作线程分别需要超过 15 秒和一分钟的时间来执行,如果这是真的,您将更快地添加线程,然后它们终止,最终导致溢出,正如 msergeant 试图说的那样,仅如果旧的工作线程已完成,则添加一个新线程。
@marr75
@zac
both of these are good advice, but why not:
this however assumes that your doing a relatively light task
if your doing a heavier task like a SQL query and insert or something or other just make sure the thread kills itself when done.
You could be getting possible overflow because your 15s and min worker threads take longer than 15s and a min respectively to execute, if this is true you will be adding threads faster then they terminate eventually leading to an overflow as msergeant was trying to say, only add a new thread if your old worker thread is finished.