3

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

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

4

2 回答 2

2

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

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

于 2013-03-21T09:37:56.443 回答
1

由于您使用的是实现IProducerConsumerCollection的 ConcurrentStack,因此您可以使用BlockingCollection包装它(通过使用此构造函数创建一个)。这提供了一个CompleteAdding()方法,该方法允许您指示数据的结束。

底层的 IProducerConsumerCollection 将用于存储项目,因此它的行为仍然类似于堆栈,因为它是 LIFO。

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

也许这对你有用?

于 2013-03-21T08:52:36.953 回答