我有ConcurrentStack,其中每个项目都是某些网络资源的网址。我还有N个线程(实际上是Tasks
),每个线程从堆栈进程中弹出一个项目,并根据某些条件将结果(结果是集合)添加到此堆栈或其他输出队列。应该这样做,直到堆栈变空。
识别此过程结束并停止此任务的更优雅方式是什么?换句话说,如何识别堆栈是空的并且没有执行任务将向堆栈添加更多项目
答案 0 :(得分:2)
终止条件似乎是从堆栈中读取的所有任务都 all 等待项目堆积到堆栈中。当然,只有当您为任务提供被动等待该事件的方法时,才会发生这种情况。根据其他答案的建议,您可以在BlockingCollection
类之上使用ConcurrentStack
来实现同步。
关于终止,最简单的方法是让一个任务(终止任务)等待那个条件,所有其他任务操作一个整数来表示等待的任务数,在阻塞集合之前递增它,然后递减它获得一个项目。当该数字达到堆栈的可能读取器总数时,当前尝试获取项目的任务会在阻塞集合之前触发条件变量,这将唤醒终止线程。
答案 1 :(得分:1)
由于您使用的是实现IProducerConsumerCollection的ConcurrentStack,因此可以使用BlockingCollection(使用this constructor创建一个)来包装它。这提供了CompleteAdding()方法,允许您指示数据的结束。
底层的IProducerConsumerCollection将用于存储项目,因此它在LIFO方面的行为仍然像堆栈一样。
您需要切换到使用其中一个GetConsumingEnumerable()重载来使用数据。我发现这是处理优雅任务终止的最优雅和最强大的方法。
也许这对你有用吗?