#wcf #.net-4.0 #workflow-foundation-4
#wcf #.net-4.0 #workflow-foundation-4
Вопрос:
У меня есть служба Workflow, в которой есть несколько приемников, которые прослушивают очереди MSMQ. Я хотел бы реализовать следующее поведение:
- Если возникает исключение корреляции (т. Е. экземпляр рабочего процесса удален), выбросьте сообщение.
- Если возникает исключение InstanceLockException (т.Е. Этот экземпляр workflow выполняет что-то на другом сервере), поместите сообщение в очередь повторных попыток.
Я попытался включить TransactedReceiveScope для операций получения, но это поместит сообщение в очередь повторных попыток из-за ошибки корреляции. Кроме того, это вызывает множество проблем при большой нагрузке.
Без TransactedReceiveScope сообщение отбрасывается при возникновении исключения InstanceLockException.
Есть ли способ реализовать это поведение (возможно, с помощью расширений поведения)?
Ответ №1:
Вы можете реализовать IErrorHandler для WCF, чтобы перехватывать все необработанные исключения, независимо от того, генерируется ли вашим приложением или WCF. С привязкой NETMSMQ нужно быть осторожным: ошибка в этом обработчике означает, что сообщение было «успешно» обработано и оно будет удалено из очереди. В вашем случае, когда возникает исключение InstanceLockException, вам придется оставить его необработанным, если вы хотите, чтобы произошла встроенная обработка повторных попыток MSMQ 4. Вам также необходимо разрешить исключение PoisonMessageException оставаться необработанным для правильной повторной попытки MSMQ.
Комментарии:
1. У меня это не работает. Я пытался вернуть True для HandleException, но сообщение всегда помещается в очередь повторных попыток. Я думаю, что эта обработка ошибок должна быть обнаружена ранее в конвейере.
2. Это единственная точка, в которой WCF позволит вам работать с исключениями, других точек расширения нет. Чтобы сообщить MSMQ, что сообщение было «успешно» обработано при возникновении исключения, которое вы не хотите повторять, вам необходимо предоставить FaultException в методе ProvideFault с подходящим названием. Взаимодействие MSMQ с WCF не позволит вам «выбросить» исключение. Кстати: все, что возвращает true для метода HandleError, сообщает WCF, что это последний IErrorHandler, который был вызван, это не влияет на фактическое исключение, которое было захвачено. Обычно HandleError полезен только для регистрации исключений.
3. Я реализовал метод ProvideFault и установил ‘ошибка сообщения ref’, создав новое FaultException, FaultException. CreateMessageFault(), ошибка = Сообщение. Создайте сообщение. Однако сообщения с ошибкой по-прежнему попадают в очередь повторных попыток. Существует ли особый тип FaultException, который мне нужно создать? Есть ли какие-либо поля, которые мне нужно установить?
4. Похоже, что обработчик ошибок не запускается WCF. Стандартное исключение FaultException подойдет для создания ошибки soap, которая вам нужна. Для устранения неполадок добавьте код в HandleError для записи исключения в файл журнала. Также убедитесь, что вы не создаете ошибку для любого исключения типа PoisonMessageException, поскольку это будет мешать взаимодействию MSMQ / WCF. Запустите службу для создания тестируемых исключений и убедитесь, что они записаны в файл журнала. Кроме того, может потребоваться включить ведение журнала в очереди MSMQ, используемой службой, чтобы знать, что обрабатывается.
5. Спасибо за объяснение. Я решил не заниматься какой-либо обработкой ошибок и позволить сообщениям повторяться до тех пор, пока они не попадут в очередь просроченных писем.
Ответ №2:
Я не знаком с использованием Workflow, но, зная, как работают MSMQ и WCF, вы могли бы попробовать это
При возникновении исключения CorrelationException:
- Перехватить исключение
- Возврат из вашего метода обслуживания
Поскольку ваш метод service не генерирует исключение, он подумает, что сообщение было успешно обработано, и удалит его из очереди.
При возникновении исключения InstanceLockException:
- Перехватить исключение
- повторно удалить исключение
Поскольку ваш метод service выдает исключение, он подумает, что сообщение не было успешно обработано, и переместит его в очередь повторных попыток.
Комментарии:
1. Да, однако все эти исключения возникают внутри конвейера WCF, поэтому у меня нет возможности перехватывать и обрабатывать эти исключения.
Ответ №3:
Я думаю, вам придется создать пользовательское поведение WCF для перехвата этих исключений.