我正在创建一个Windows服务,其中包含2个单独的组件:
1个组件创建作业并将其插入数据库(1个线程)
第二个组件处理这些作业(线程池中多个固定线程数)
只要服务正在运行,这两个组件将始终运行。
我所坚持的是确定如何实现此线程池。我已经进行了一些研究,似乎有很多方法可以做到这一点,例如创建一个覆盖方法“ThreadPoolCallback”的类,并使用ThreadPool.QueueUserWorkItem将工作项排队。 http://msdn.microsoft.com/en-us/library/3dasc8as.aspx
但是,在给出的示例中,它似乎不适合我的情况。我想最初在线程池中创建固定数量的线程。然后将其送入作业进行处理。我该怎么做呢?
//与线程池一起使用的包装方法。
public void ThreadPoolCallback(Object threadContext)
{
int threadIndex = (int)threadContext;
Console.WriteLine("thread {0} started...", threadIndex);
_fibOfN = Calculate(_n);
Console.WriteLine("thread {0} result calculated...", threadIndex);
_doneEvent.Set();
}
Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
const int FibonacciCalculations = 10;
for (int i = 0; i < FibonacciCalculations; i++)
{
ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
}
最佳答案
创建工作项的BlockingCollection。创建作业的线程将它们添加到此集合中。
创建固定数量的持久线程,这些持久线程从该BlockingCollection
中读取项目并进行处理。就像是:
BlockingCollection<WorkItem> WorkItems = new BlockingCollection<WorkItem>();
void WorkerThreadProc()
{
foreach (var item in WorkItems.GetConsumingEnumerable())
{
// process item
}
}
多个工作线程可以同时执行该操作。
BlockingCollection
支持多个读取器和写入器,因此没有您需要处理的并发问题。有关使用一个消费者和一个生产者的示例,请参见我的博客文章Simple Multithreading, part 2。添加多个使用者是为每个使用者分配新任务的一个非常简单的问题。
另一种方法是使用信号量来控制当前正在处理多少个作业。我在this answer中演示了如何做到这一点。但是,我认为共享的
BlockingCollection
通常是更好的解决方案。关于c# - Windows服务中的 worker 线程池?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20429716/