我正在创建一个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/

10-11 03:35