Сигнализация задачи производителя из задачи потребителя при работе с BlockingCollection - PullRequest
1 голос
/ 25 января 2012

У меня есть довольно простое приложение, которое использует задачу Producer и задачу Consumer для работы с файлами.Он основан на примере, приведенном здесь http://msdn.microsoft.com/en-us/library/dd267312.aspx

Основа программы заключается в том, что задача Producer перечисляет файлы на моем жестком диске, вычисляет их значения хеш-функции и выполняет несколько других задач.Как только источник завершит работу с файлом, он запрашивает файл, а получатель затем захватывает его.

Задача потребителя должна подключиться к удаленному серверу и попытаться загрузить файл.Тем не менее, если Потребитель обнаруживает ошибку, например, не может подключиться к удаленному серверу, мне нужно, чтобы он дал сигнал задаче Производителя, что он должен остановить то, что он делает, и завершить работу.Если сервер не работает или выходит из строя, то для Продюсера нет необходимости продолжать циклически перебирать тысячи файлов.

Я видел множество примеров сигнализации задачи «Потребитель» из задачи «Производитель» с помощью .CompleteAdding() на объекте BlockingCollection, но я заблудился относительно того, как отправить сигнал получателю от потребителя о том, что он должен прекратить производство.

1 Ответ

0 голосов
/ 25 января 2012

Вы можете использовать очередь возврата. Если один из элементов генерирует ошибку / исключение, вы можете загрузить его с данными об ошибках и поставить его в очередь производителю. Производителю следует попробовать TryTake () из очереди возврата непосредственно перед созданием нового элемента и соответствующим образом обработать любой возвращенный элемент. Это лучше, чем использование некоторого атомарного логического значения, позволяющего элементу отправлять обратные сигналы с расширенной информацией об ошибках, которая может быть использована для принятия решения о том, какое действие предпринять - производитель не всегда хочет / должен останавливаться. Кроме того, вы можете затем поставить ошибочные элементы в очередь в список графического интерфейса и / или регистратор.

Соблазнительно сказать, что потребитель должен возвращать товары в любом случае, независимо от того, ошибочны они или нет, чтобы их можно было повторно использовать вместо создания новых. Это, однако, создает задержку при обнаружении / воздействии на ошибки, если только вы не используете две очереди возврата для определения приоритетов ошибок.

Да, еще одна вещь - используя описанный выше дизайн, если он должен остановиться, производитель может сохранить элементы с ошибками в локальной очереди, переиздавая время от времени. Если сервер возвращается (как указано в возврате успешного элемента), производитель может повторно выполнить ошибочные задания из локальной очереди, прежде чем генерировать новые. Осторожно, это может сделать вашу систему загрузки устойчивой к перезагрузкам сервера.

...