2015-04-05 82 views
2

當我打電話QueueClient.Close(),它總是會引發一個異常:如何優雅地關閉Azure ServiceBus QueueClient?

的操作,因爲實體已經關閉 或中止無法執行。

即使隊列爲空,它也會引發異常。

雖然我通過使用OnMessageOptions.ExceptionReceived來處理它,但它令我煩惱。我的代碼有問題嗎?

如何優雅地停止QueueClient?

[啓動和停止消息]

// create a QueueClient with Exception handler. 
var queueClient = queueManager.GetStorage<UpdateTriggerQueueClient>(); 
var options = new OnMessageOptions 
{ 
    AutoComplete = false 
}; 
// When the Close() called, it always handles an exception. 
options.ExceptionReceived += (sender, args) => 
    logger.Error("An excepion occurred.", args.Exception); 

// prepare a CancellationTokenSource. 
var cancellationTokenSource = new CancellationTokenSource(); 
var cancellationToken = cancellationTokenSource.Token; 

// start message pump. 
queueClient.OnMessageAsync(async message => 
      await DoWork(message, cancellationToken), options); 

// sometime after, stop(cancel) the work. 
Task.Delay(5000).Wait(); 
cancellationTokenSource.Cancel(); 

// some code to wait every in-progress messages finished. 
// ... 

// close the client. 
queueClient.Close(); 

[DoWork的方法]

private async Task DoWork(BrokeredMessage message, CancellationToken cancellationToken) 
{ 
    logger.Trace("begin work"); 
    // Do something cancellable work. 
    await Task.Delay(500, cancellationToken) 
     .ContinueWith(async t => 
     { 
      // complete the message when the task completed, 
      // otherwise, abandon the message. 
      if (t.Status == TaskStatus.RanToCompletion) 
      { 
       await message.CompleteAsync(); 
      } 
      else 
      { 
       await message.AbandonAsync(); 
      } 
     }) 
     .ContinueWith(t => 
     { 
      // cleanup 
      logger.Trace("end work"); 
     }); 
} 

回答

-1

我在https://msdn.microsoft.com/en-us/library/azure/hh528527.aspx讀了接近的連接由消息的工廠管理不應該叫。

this.mSubscriptionClient.OnMessage(
      (pMessage) => 
      { 
       try 
       { 
        // Will block the current thread if Stop is called. 
        this.mPauseProcessingEvent.WaitOne(); 

        // Execute processing task here 
        pProcessMessageTask(pMessage); 
       } 
       catch(Exception ex) 
       { 
        this.RaiseOnLogMessageEvent(pMessage, ex); 
       } 
      }, 
      options); 

然後當你準備停止

this.mPauseProcessingEvent.Reset(); 
mSubscriptionClient.Close(); 

的數據類型是

private ManualResetEvent mPauseProcessingEvent; 
+0

我叫'Close'方法,因爲我需要停止接收消息QueueClient。你能解釋一下如何在不調用'Close'的情況下停止接收消息嗎? – 2015-06-16 03:02:19

+0

鏈接到https://msdn.microsoft.com/en-us/library/azure/hh528527.aspx的頁面顯示「你不應該關閉消息發送工廠或隊列,主題和訂閱客戶端,然後在發送下一條消息時重新創建它們。「因此,它是在每次處理消息時都要關閉並重新創建客戶端,而不是關於什麼時候你想關閉客戶端,因爲你做得很好。 – AndyJ 2017-08-30 10:17:46

0

可以被收到與更新的訂閱停止所有消息:

_namespaceManager.UpdateSubscription(new SubscriptionDescription(_strTopic, _strSubscription) 
    { 
    Status = EntityStatus.ReceiveDisabled 
    }); 

這可能解決你的問題,即使它不完全是你問的。 (我也試圖找出如何關閉()正確。

你也將需要更新的狀態重新開始接收。