2016-12-22 5 views
1

При включении централизованного хранилища с MSMQ есть ли что-то еще, что необходимо изменить? Вот что у меня есть, но код не будет полностью загружен. Работает, как ожидается, если я отключу централизованное хранилище.Централизованное хранилище Rebus MSMQ

_messageActivator = new BuiltinHandlerActivator(); 
_messageActivator.Register<PosOnlineHandler>(() => new PosOnlineHandler(WriteOutputAsync)); 
_messageActivator.Register<PumpDownHandler>(() => new PumpDownHandler(WriteOutputAsync)); 
_messageActivator.Register<MetersRequestHandler>(() => new MetersRequestHandler(WriteOutputAsync, _messageActivator.Bus)); 
_messageActivator.Register<CreditAuthorizationHandler>(() => new CreditAuthorizationHandler(WriteOutputAsync, _messageActivator.Bus)); 
Configure.With(_messageActivator) 
    .Transport(t => t.UseMsmq("consumerServiceQueue")) 
    .Routing(r => r.TypeBased() 
     .Map<PumpDownEvent>("publisherServiceQueue") 
     .Map<PosOnlineEvent>("publisherServiceQueue") 
     .Map<MetersResponse>("publisherServiceQueue") 
     .Map<CreditAuthorizationResponse>("publisherServiceQueue")) 
    .Subscriptions(s => s.StoreInSqlServer(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=test;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", "RebusSubscriptions", true, true)) 
    .Start(); 
    _messageActivator.Bus.Subscribe<PumpDownEvent>().Wait(); 
    _messageActivator.Bus.Subscribe<PosOnlineEvent>().Wait(); 

Спасибо. Scott C.

+0

Что вы подразумеваете под кодом, который не будет полностью загружен? – mookid8000

+0

Извините, он зависает под подписчиком(). Подождите(). ...., Я вижу, что в образце MessageBus используется централизованное хранилище MSMQ, поэтому я проверю это позже, чтобы узнать, получил ли я тот же результат. – scottctr

+0

и не истекает через 30 секунд или 1 минуту или что-то в этом роде? – mookid8000

ответ

1

Пояснение: Windows Forms (о котором вы упомянули, что вы вызываете этот код) использует планировщик задач, который настаивает на продолжении продолжений в потоке пользовательского интерфейса.

Это очень полезно в контексте Windows Forms, поскольку управление может управляться только из этого потока.

Проблема возникает, когда вы звоните .Wait() (или .Result) на Task, потому что блокирует текущий поток, ожидая все продолжения, чтобы закончить выполнение - но так как текущий поток блокируется, он никогда не будет доступен для запуска продолжений , что приводит к тупиковой ситуации.

Адрес another question that discusses this issue. Как вы можете видеть, проблема никоим образом не является специфичной для Rebus, это просто общая черта сочетания асинхронизации Task и Windows Forms (или WPF или ASP.NET, если на то пошло).

Я предлагаю вам изучить, как правильно запустить async кода во время инициализации System.Windows.Forms.Form, так что вы можете установить свои подписки в рекомендуемом способе, await т Task S:

await bus.Subscribe<PumpDownEvent>(); 

await bus.Subscribe<PosOnlineEvent>(); 

Почему эта проблема показывается только тогда, когда isCentralized: true передан в метод конфигурации StoreInSqlServer?

Проще говоря, это происходит потому, что на самом деле асинхронный процесс фактически не выполняется, когда Rebus настроен на использование децентрализованного хранилища подписки с MSMQ в качестве транспорта.

При запуске централизованный абонент регистрируется как абонент в хранилище подписки. В конфигурации, которую вы используете, это означает, что SqlConnection получает (асинхронно), а затем выполняется (асинхронно) ExecuteNonQueryAsync, вставляя строку в таблицу [RebusSubscriptions].

При запуске децентрализованный абонент регистрируется как абонент, отправив издателю SubscribeRequest. С MSMQ эта операция просто выполняется синхронно без await с одной вещью, потому что у MSMQ нет API, который возвращает Task s.

Если вы использовали SQL Server, Azure Service Bus, Amazon SQS и т. Д. В качестве транспорта, то при отправке SubscribeRequest было бы несколько асинхронных вещей, и тогда у вас был бы тот же самый тупик.

Надеюсь, это объяснит это :)

+0

Спасибо Mookid. Любое понимание того, почему это происходит только тогда, когда IsCentralized установлено в true? – scottctr

+0

Отличный вопрос! :) Я расширил ответ с объяснением .... – mookid8000