2016-12-22 30 views
1

當啓用集中存儲與MSMQ,有沒有別的什麼需要改變?這是我的,但代碼不會完全加載。如果我禁用集中存儲,則按預期工作。滷麪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

對不起,它掛在Subscriber()。Wait()。 ....,我發現MessageBus示例使用集中的MSMQ存儲,所以稍後我會測試以查看是否得到相同的結果。 – scottctr

+0

並且在30秒或1分鐘之後沒有超時? – mookid8000

回答

1

下面是一個解釋:Windows窗體(您提到您調用此代碼)使用一個任務調度程序,堅持在UI線程上運行延續。

這是非常有用的Windows窗體背景下,因爲控制可能只從該線程被操縱。

,就會出現問題,當你調用一個Task.Wait()(或.Result),因爲這阻止當前線程,等待所有的延續執行完畢 - 但由於當前線程被阻塞,它永遠不會適用於運行延續,從而導致僵局。

這裏的another question that discusses this issue。正如你所看到的,問題是沒有辦法具體爲滷麪,那簡直是異步Task S和Windows窗體(或WPF或ASP.NET爲此事)的組合的總體特徵。

我建議你研究如何System.Windows.Forms.Form的初始化期間正常運行async代碼,這樣你就可以通過await建立以建議的方式您的訂閱荷蘭國際集團的Task S:

await bus.Subscribe<PumpDownEvent>(); 

await bus.Subscribe<PosOnlineEvent>(); 

爲什麼只有當isCentralized: true傳遞給StoreInSqlServer配置方法時,此問題纔會顯示嗎?

簡而言之,這是因爲當Rebus配置爲使用MSMQ的分散訂閱存儲作爲傳輸時,實際上並不會發生真正的異步事件。

當運行集中式時,訂戶將自己註冊爲訂閱存儲中的訂戶。隨着你使用的是意味着SqlConnection得到(異步)打開,然後一個ExecuteNonQueryAsync是(再次異步)執行,在[RebusSubscriptions]表中插入一行的配置。

當運行分散式,訂戶通過發送出版者SubscribeRequest註冊自己作爲訂戶。 隨着MSMQ這種操作剛好沒有await有個單獨的事情同步執行,因爲MSMQ沒有返回Task秒的API。

如果您使用SQL Server,Azure服務總線,Amazon SQS等作爲傳輸方式,那麼在發送SubscribeRequest時會發生一些異步事件,然後您將會遇到同樣的死鎖。

我希望能解釋一下:)

+0

謝謝Mookid。任何關於爲什麼只有在IsCentralized時纔會出現的見解設置爲true? – scottctr

+0

優秀的問題! :)我已經擴大了答案與解釋.... – mookid8000