Multithreading 如何实现线程池。加入?
我正在编写一个使用Multithreading 如何实现线程池。加入?,multithreading,.net-3.5,windows-services,threadpool,Multithreading,.net 3.5,Windows Services,Threadpool,我正在编写一个使用ThreadPool.QueueUserWorkItem()的windows服务。每个线程都是一个短期任务 当服务停止时,我需要确保当前正在执行的所有线程都已完成。是否有某种方法等待队列自行清除?您可以在每个线程中创建一个事件(例如,ManualResetEvent),并将其保存在一个同步列表中(使用lock构造)。设置事件或在任务完成时将其从列表中删除 当您想要加入时,可以使用WaitHandle.WaitAll()等待所有事件发出信号 这是一个黑客,但我看不出如何将它简化为
ThreadPool.QueueUserWorkItem()
的windows服务。每个线程都是一个短期任务
当服务停止时,我需要确保当前正在执行的所有线程都已完成。是否有某种方法等待队列自行清除?您可以在每个线程中创建一个事件(例如,ManualResetEvent
),并将其保存在一个同步列表中(使用lock
构造)。设置事件或在任务完成时将其从列表中删除
当您想要加入时,可以使用WaitHandle.WaitAll
()等待所有事件发出信号
这是一个黑客,但我看不出如何将它简化为更简单的东西
编辑:另外,您可以确保没有发布新事件,然后等待几秒钟。如果它们确实是短暂的,你就没有问题了。更简单,但更粗糙
最后,如果只是很短的时间,服务将不会退出,直到所有线程都死掉(除非它们是后台线程);因此,根据我的经验,如果时间很短,维修控制经理一秒钟左右都不会介意,你可以让它们过期。这样做的标准模式是使用一个计数器,它保存挂起的工作项的数量,以及一个当计数器达到零时发出信号的
ManualResetEvent
。这通常比为每个工作项使用WaitHandle
要好,因为当同时有很多工作项时,它的伸缩性不太好。另外,一些静态的WaitHandle
方法只接受最多64个实例
// Initialize to 1 because we are going to treat the current thread as
// a work item as well. This is to avoid a race that could occur when
// one work item gets queued and completed before the next work item
// is queued.
int count = 1;
var finished = new ManualResetEvent(false);
try
{
while (...)
{
Interlocked.Increment(ref counter);
ThreadPool.QueueUserWorkItem(
delegate(object state)
{
try
{
// Your task goes here.
}
finally
{
// Decrement the counter to indicate the work item is done.
if (Interlocked.Decrement(ref count) == 0)
{
finished.Set();
}
}
});
}
}
finally
{
// Decrement the counter to indicate the queueing thread is done.
if (Interlocked.Decrement(ref count) == 0)
{
finished.Set();
}
}
finished.WaitOne();
它们应该是短期的,但对于我的用例,我需要比“应该工作”更多的保证。我正在考虑使用一个互锁线程计数器来跟踪池中的线程数,并等待线程数等于零。实际上,我更喜欢你的第一个建议而不是计数器。