我已经阅读了其他一些类似但不相同的链接,试图找到一些答案: How to consume a BlockingCollection<T> in batches
然而,(在上面的链接中)没有使用GetConsumingEnumerable似乎很可疑。
在消费者(应该是单数)清空收藏品时,有效阻止生产者的正确方法是什么?
[我们希望进行批处理,因为每个批处理都会进行一次Web服务调用,如果每个消息/项目都需要自己的调用,这将成为瓶颈。批量处理消息/项目是解决此瓶颈的方法。]
理想情况下:
1)接收消息
2)推进集合的新生产者任务
3)当收集&#39;完整&#39; (任意限制),阻止所有生产者,新的消费者任务消耗所有的集合,然后取消阻止生产者。
换句话说;我希望(并行生产者)xor(单一消费者)随时对集合采取行动。
这似乎应该在此之前完成,但我似乎无法找到专门以这种方式行事的代码段。
感谢您的帮助。
答案 0 :(得分:0)
使用这个模型,所有的工作都是完全序列化的,也就是说你从来没有一个以上的东西&#34;一次工作。生产者是工作,还是消费者。因此,您并不需要从生产者和消费者那里操作的集合,而是可以让生产者生成批量的传统集合,消费者在完成后会消耗这些集合。它可能看起来像这样:
public Task<List<Thing>> Produce(Message message)
{
//...
}
public Task Consume(List<Thing> data)
{
//...
}
public async Task MessageReceived(Message message)
{
while(HaveMoreBatches(message))
{
await Consume(await Produce(message));
}
}
这使您可以生成批次,然后使用它,然后生成另一个批次,然后使用它等,直到不再生成批次为止。
答案 1 :(得分:0)
根据你的模糊描述,我相信双缓冲是你想要的。
只需创建两个缓冲区。生产者写到一个直到。当它变满或当计时器退出时,它会被“交换”为第二个,并且生产者开始写入新的。然后消费者开始阅读第一个现在已满的缓冲区。
这允许生产者和消费者同时运行。并确保消费者在重复循环之前处理所有先前创建的工作。