2012-01-25 46 views
1

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

该程序的基础知识是生产者任务枚举硬盘上的文件并计算其散列值并执行其他一些操作。一旦生产者完成了一个文件的工作,它将Enques文件和消费者抓住它。

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

我已经看到很多样品通过在BlockingCollection对象上使用.CompleteAdding()从生产者任务中发信号通知消费者任务,但是我失去了如何从消费者向生产者发送信号以致它应该停止生产。

回答

0

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

无论如何,消费者都应该退货,无论他们是否存在错误,这样他们就可以被重新使用,并且一直都在创造新产品。然而,这会导致检测/作用错误的延迟,除非您使用两个返回队列来优先处理错误返回。

哦 - 另一件事 - 使用上述设计,如果必须停止,生产者可以在本地队列中保留错误项目,偶尔重新发布。如果服务器重新启动(如成功项目的返回所示),那么生产者可以重新发布本地队列中的错误作业,然后再生成新的作业。小心,这可能会使您的上传系统适应服务器重启。

+0

因此,如果我正确理解你的话......我会创建第二个BlockingCollection来包含错误条件,然后生产者将对它使用TryTake? – forcedfx

+0

是的。我会排队整个项目 - 给它一些额外的数据成员来保存可能产生的任何错误数据。如果消费者退回,它将包含文件规格,主机名和您最初发送给消费者的任何其他内容以及错误数据 - 可能包含错误编号/枚举和/或文本错误消息。这使日志记录/显示错误或稍后重试很容易,(清除错误信息并再次将其排入消费者)。 –

相关问题