【问题标题】:Signalling a producer task from a consumer task when working with a BlockingCollection使用 BlockingCollection 时从消费者任务向生产者任务发送信号
【发布时间】:2012-02-18 17:40:58
【问题描述】:

我有一个非常基本的应用程序,它使用生产者任务和消费者任务来处理文件。它基于此处的示例http://msdn.microsoft.com/en-us/library/dd267312.aspx

该程序的基础是 Producer 任务枚举我硬盘上的文件并计算它们的哈希值并执行其他一些操作。一旦 Producer 处理完一个文件,它就会 Enques 文件,然后 Consumer 抓取它。

Consumer 任务必须连接到远程服务器并尝试上传文件。但是,如果消费者遇到错误,例如无法连接到远程服务器,我需要它向生产者任务发出信号,告知它应该停止正在做的事情并终止。如果服务器宕机或宕机,生产者无需继续循环浏览数千个文件。

我已经看到了大量通过在 BlockingCollection 对象上使用 .CompleteAdding() 从 Producer 任务向 Consumer 任务发出信号的示例,但我不知道如何从 Consumer 向 Producer 发送信号,表明它应该停止生产.

【问题讨论】:

    标签: c#-4.0 consumer producer blockingcollection


    【解决方案1】:

    您可以使用返回队列。如果其中一项产生错误/异常,您可以使用错误数据加载它并将其排队返回给生产者。生产者应该在生成新项目之前从返回队列中 TryTake() 并适当地处理任何返回的项目。这优于使用一些原子布尔值,它使项目能够用扩展的错误信息发回信号,这些信息可用于决定采取什么行动——生产者可能并不总是想要/需要停止。此外,您还可以将错误项目排队到 GUI 列表和/或记录器。

    很容易说消费者无论如何都应该退回商品,无论它们是否出错,以便它们可以被重复使用以一直创建新商品。但是,除非您使用两个返回队列来确定错误返回的优先级,否则这会在检测/处理错误时引入延迟。

    哦 - 另一件事 - 使用上述设计,如果它必须停止,生产者可以将错误的项目保留在本地队列中,偶尔重新发布一个。如果服务器恢复正常(如成功项目的返回所示),生产者可以在生成更多新作业之前再次从本地队列重新发出错误作业。小心,这可以让您的上传系统适应服务器重启。

    【讨论】:

    • 那么,如果我理解正确的话……我会创建第二个 BlockingCollection 来包含错误条件,然后 Producer 会对其使用 TryTake?
    • 是的。我会将整个项目排入队列 - 给它一些额外的数据成员来保存可能生成的任何错误数据。如果它被消费者退回,它将包含文件规范、主机名和您最初发送给消费者的任何其他内容以及错误数据——可能是一些错误编号/枚举和/或文本错误消息。这使得记录/显示错误或稍后重试变得容易,(清除错误信息并将其再次排队给消费者)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多