在多个线程中处理堆栈项

本文关键字:处理 堆栈 线程 | 更新日期: 2023-09-27 18:05:09

我有一个ConcurrentStack,其中每个项目是URL到一些web资源。我还有N个线程(实际上是Tasks),每个线程都从堆栈进程中弹出一个项目,并根据某些标准将结果(结果是集合)添加到该堆栈或其他输出队列。这应该执行,直到堆栈变为空。

识别此过程结束并停止此任务的更优雅的方法是什么?换句话说,如何识别堆栈是空的,并且没有正在执行的任务将更多的项添加到堆栈

在多个线程中处理堆栈项

终止条件似乎是当所有从堆栈中读取的任务等待一个项目被堆栈堆积。当然,只有当您为任务提供一种被动等待该事件的方法时,才会发生这种情况。正如其他答案所建议的那样,您可以在ConcurrentStack类之上使用BlockingCollection来实现同步。

关于终止,最简单的方法是让一个任务(终止任务)等待该条件,所有其他任务操作一个表示等待任务数量的整数,在阻塞集合之前将其递增,在获取项时将其递减。当该数字达到堆栈可能的读取器总数时,当前尝试获取项目的任务在阻塞集合之前触发条件变量,这将唤醒终止线程。

因为你正在使用ConcurrentStack,它实现了IProducerConsumerCollection,你可以用BlockingCollection包装它(通过使用这个构造函数创建一个)。它提供了一个CompleteAdding()方法,允许你指定数据的结束。

底层的IProducerConsumerCollection将用于存储项目,因此它在后进先出方面仍然表现得像堆栈。

您需要切换到使用GetConsumingEnumerable()重载之一来消费数据。我发现这是处理优雅任务终止的最优雅、最强大的方式。

也许这对你有用?