2017-08-11 35 views
1

當使用async/await時,我關心處理客戶端時處理郵件。考慮以下幾點:正在處理Azure服務總線客戶端的同時正在處理郵件

  1. 在類

  2. 隊列客戶端處理的消息,並在全球範圍內初始化一個隊列客戶queueClient和存儲對它的引用調用一些應用程序代碼來處理它,這可能最終做一些異步數據庫工作或調用遠程API。

  3. 考慮應用程序是一個窗口服務,當應該關閉該服務時發出信號的CloseAsync方法。在此方法中,我致電queueClient.CloseAsync()

  4. 正在完成的步驟2中的工作完成並致電message.Complete()。此時我假設queueClient已關閉,並且該消息將被視爲失敗。

確保隊列客戶端不再處理消息並等待任何當前正在處理的消息完成後才關閉的最佳實踐是什麼?

回答

1

您可以在等待對queueClient.CloseAsync()的調用之前,使用CancellationToken取消步驟2的工作並/或等待步驟4中的異步消息處理代碼。我認爲你與Tasks and Cancellation familiair。

等待消息處理任務

  1. 初始化隊列客戶端queueClient和參考存儲它在類

  2. 隊列客戶端處理的消息和全球範圍調用一些應用程序代碼來處理它,這可能最終會做一些異步數據庫工作或調用遠程API,例如public Task HandleMessageAsync() {..}。在全局範圍內存儲對此任務的引用。例如private Task messageHandleTask;

  3. 考慮應用程序是一個窗口服務,它帶有一個CloseAsync方法,該方法在服務應該關閉時發出信號。在這種方法中,我先打電話await messageHandleTask然後await queueClient.CloseAsync()

  4. 我們都活得很長很開心。

在這種情況下,服務將不會完全停止,直到消息處理完成。

取消的消息處理任務

  1. 初始化隊列客戶queueClient並存儲在類

  2. 隊列客戶端處理的消息在全球範圍對它的引用,並調用一些應用程序代碼來處理它,傳遞一個CancellationToken,這可能最終會做一些異步數據庫工作或調用遠程API,例如public Task HandleMessageAsync(CancellationToken token) {..}。在全局範圍內存儲對此任務的引用。

  3. 考慮應用程序是一個窗口服務,當應該關閉該服務時發出信號的CloseAsync方法。在此方法中,我先撥打cancellationTokenSource.Cancel(),然後await messageHandleTask,最後await queueClient.CloseAsync()

  4. 我們都活得很長很開心。

在這種情況下,消息處理代碼,只是調用message.Complete().您檢查任何取消之前:token.ThrowIfCancellationRequested。在這種情況下,當服務關閉時,消息永遠不會達到完成狀態,並會在稍後處理。 (請注意,我不知道所涉及的代碼,因此如果在取消發生之前已完成部分工作,此情況可能會非常複雜)請務必處理任何OperationCanceledException

在多個消息的處理併發可以使用await Task.WhenAll(..)

+1

順便說一個情況下,如果這個答案套房你,給我一個鬆餅,他們看起來美味;-) –

+0

感謝詳細的解答。清楚的是,我不想介紹在處理消息時回滾應用程序正在進行的部分更改的複雜性,我寧願讓它在完成服務關閉之前完成,因此它似乎是第一個例子。是最簡單的,我目前正在做的是正確的方式?我曾假設,由於等待會讓程序在數據庫上等待時繼續執行,因此在數據庫將控制權返回給應用程序之前,將調用queueClient.CloseAsync方法。 –

+1

確實,第一個例子最適合您的場景。如果您'等待'首先與de數據庫通信的方法,然後等待'queueClient.CloseAsync()'的調用,那麼您可以確信第一個任務在關閉客戶端之前完成。 –

相關問題