2012-01-25 45 views
1

我有一個非常基本的應用程序,它使用生產者任務和消費者任務來處理文件。它基於此處的示例http://msdn.microsoft.com/en-us/library/dd267312.aspx使用BlockingCollection從消費者任務發信號通知生產者任務

該程序的基礎知識是生產者任務枚舉硬盤上的文件並計算其散列值並執行其他一些操作。一旦生產者完成了一個文件的工作,它將Enques文件和消費者抓住它。

消費者任務必須連接到遠程服務器並嘗試上載文件。但是,如果消費者遇到錯誤,例如無法連接到遠程服務器,我需要它向生產者任務發出信號,告知它應該停止它正在做的事情並終止它。如果服務器停機或停機,則生產者無需繼續循環訪問數千個文件。

我已經看到很多樣品通過在BlockingCollection對象上使用.CompleteAdding()從生產者任務中發信號通知消費者任務,但是我失去了如何從消費者向生產者發送信號以致它應該停止生產。

回答

0

您可以使用返回隊列。如果其中一個項目生成錯誤/異常,則可以將其加載錯誤數據並將其排回到生產者。在生成新項目並恰當處理任何返回項目之前,生產者應該從返回隊列中TryTake()。這使用了一些原子布爾值,通過使項目能夠用擴展的錯誤信息發回信號來決定採取什麼動作 - 製作者可能並不總是需要停止。此外,您可以將錯誤項目排入GUI列表和/或記錄器。

無論如何,消費者都應該退貨,無論他們是否存在錯誤,這樣他們就可以被重新使用,並且一直都在創造新產品。然而,這會導致檢測/作用錯誤的延遲,除非您使用兩個返回隊列來優先處理錯誤返回。

哦 - 另一件事 - 使用上述設計,如果必須停止,生產者可以在本地隊列中保留錯誤項目,偶爾重新發布。如果服務器重新啓動(如成功項目的返回所示),那麼生產者可以重新發布本地隊列中的錯誤作業,然後再生成新的作業。小心,這可能會使您的上傳系統適應服務器重啓。

+0

因此,如果我正確理解你的話......我會創建第二個BlockingCollection來包含錯誤條件,然後生產者將對它使用TryTake? – forcedfx

+0

是的。我會排隊整個項目 - 給它一些額外的數據成員來保存可能產生的任何錯誤數據。如果消費者退回,它將包含文件規格,主機名和您最初發送給消費者的任何其他內容以及錯誤數據 - 可能包含錯誤編號/枚舉和/或文本錯誤消息。這使日誌記錄/顯示錯誤或稍後重試很容易,(清除錯誤信息並再次將其排入消費者)。 –

相關問題