在Window服务中的工作线程池?

时间:2013-12-06 17:12:28

标签: c# multithreading windows-services

我正在创建一个包含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);
}

2 个答案:

答案 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