я скопирую ответ, который я дал в Particular Software Google Group ...
Я процитирую себя прямо здесь:
Реализация IWantToRunWhenBusStartsAndStops является отличным местом, чтобы создать быстрый интерфейс для тестирования сообщений во время отладки, позволяя отправлять сообщения на основе ввода в консоль. Помимо этого, нередко широко используется их в производственной системе. Одним из возможных вариантов использования продукта будет предоставление ресурса, необходимого конечной точке при запуске, а затем оторвать его, когда конечная точка остановится.
Я думаю, что если бы я мог добавить немного акцента, это было бы «широко распространено».Я не пытаюсь сказать, что у вас не будет/не может быть IWantToRunWhenBusStartsAndStops в производственном коде или что их избежать - это лучшая практика. Я пытаюсь сказать, что тонна из них, вероятно, является запахом кода.
Выше этого абзаца в книге я предупреждаю о том, что IWantToRunWhenBusStartsAndStops не имеет каких-либо внешних транзакций или не пытается или поймает материал. Это действительно ключевая часть. Если вы закончите бросать исключение в IWantToRunWhenBusStartsAndStops, вы можете столкнуться с большими проблемами. Если вы используете что-то вроде .NET Timer, а затем генерируете исключение, вы можете разрушить свой процесс!
Позвольте мне рассказать вам, как я это испортил в своей первой в истории системе NServiceBus. Система (все еще используемая сегодня, из того, что я слышу) несет ответственность за глотание более 3000 RSS-каналов (вероятно, намного больше, чем сейчас) в CMS. Поэтому обрабатывайте каждый канал, разбивая его на элементы, изменяя размер изображений, кодируя прикрепленное видео для мобильных устройств ... все эти вещи обрабатывались обработчиками сообщений NServiceBus, которые были масштабированы на несколько серверов, и это было фантастически.
Проблема заключалась в планировщике. Я реализовал это как IWantToRunWhenBusStartsAndStops (ну, на самом деле IWantToRunAtStartup в то время), и он быстро превратился в беспорядок. Я сохранил всю информацию о количестве фишек в памяти, чтобы я мог рассчитать, когда следует отменить следующую команду ProcessFeed. Я использовал класс .NET Timer и IIRC, мне в конечном итоге пришлось использовать примитивы с потоками, такие как ManualResetEvent, чтобы координировать действия. И поскольку я использовал .NET Timer, если планировщик выбрал исключение, эта конечная точка не удалась и должна была перезапуститься. Много странных краевых случаев, и это всегда было трясиной ошибок. Кроме того, это было теперь однопользовательское «приложение-командир», поэтому, когда процессоры feed/item можно было масштабировать, планировщик не смог.
Как я получил больше опыта с NServiceBus, я понял, что каждый фид должен был быть сагой, начиная с события FeedCreated, управляемого командами PauseProcessing и ResumeProcessing, используя таймауты для управления следующим временем обработки и, наконец, (возможно) закончился через событие FeedRemoved. Это было бы намного проще, и все было бы выполнено внутри обработчиков сообщений, управляемых транзакциями.
Этот опыт заставил меня быть немного недоверчивым/скептически относиться к IWantToRunWhenBusStartsAndStops. Не сказать, что это плохо, просто что-то, о чем нужно знать. Всегда будьте готовы к тому, чтобы сделать то, что вы пытаетесь сделать, не может быть лучше достигнуто по-другому.
Хорошо, возможно, это просто такой сценарий, который у нас есть, что немного необычно. Обычно вставки базы данных (это скорее случай пакетной обработки, чем сущности, которые изменяются каким-либо связанным с бизнесом событием и т. Д.), Будет проходить через обработчик команд, запущенный в рамках службы, размещенной в NSB, в этом случае метод IWantToRunWhenBusStartsAndStops.Start просто выполнит инициализацию Конечно, в то время как фактическая работа (обновление db и публикации событий) будет выполняться в обработчиках. – Ale
@Ale - см. Мое редактирование –
+1. Я действительно думаю, что ваш случай использования необычен - я предполагаю, что вы запускаете консольное приложение через планировщик? Если это так, я думаю, что это само по себе довольно необычно против работы в качестве службы Windows. Его последнее предложение в этом связанном параграфе точно описывает, как я использую IWantToRunWhenBusStartsAndStops для производства: предоставить ресурс или запустить фоновый процесс. Одним из текущих примеров является запуск самообслуживания WebAPI. –