我正在创建一个包含2个独立组件的Windows服务: 1个组件创建作业并将它们插入数据库(1个线程) 第二个组件处理这些作业(线程池中多个FIXED#个线程)
只要服务正在运行,这两个组件就会一直运行。
我坚持的是确定如何实现此线程池。我做了一些研究,似乎有很多方法可以做到这一点,例如创建一个覆盖方法“ThreadPoolCallback”的类,并使用ThreadPool.QueueUserWorkItem对工作项进行排队。 http://msdn.microsoft.com/en-us/library/3dasc8as.aspx
然而,在给出的示例中,它似乎不适合我的场景。我想最初在线程池中创建一个FIXED线程数。然后将作业提供给处理。我该怎么做?
//用于线程池的Wrapper方法。
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);
}
答案 0 :(得分:1)
创建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
通常是更好的解决方案。
答案 1 :(得分:0)
.NET线程池并非真正设计用于固定数量的线程。它旨在以最佳方式使用机器资源来执行多个相对较小的工作。
对您来说,更好的解决方案可能是实例化固定数量的BackgroundWorkers吗?有一些reasonable BW examples。