2015-04-05 3 views
2

Когда я называю QueueClient.Close(), это всегда вызывает исключение:Как правильно закрыть Azure ServiceBus QueueClient?

Операция не может быть выполнена, так как объект был закрыт или прервана.

Это вызывает исключение, даже если очередь была пуста.

Хотя я обрабатываю его, используя OnMessageOptions.ExceptionReceived, но это меня раздражает. Что-то не так с моим кодом?

Как изящно остановить QueueClient?

[Start, и остановить передачу сообщений]

// 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'? –

+0

Страница, связанная с https://msdn.microsoft.com/en-us/library/azure/hh528527.aspx, говорит:« Вы не должны закрывать серверах обмена сообщениями или клиентах очереди, темы и подписки после отправки сообщения, а затем повторно создайте их при отправке следующего сообщения ». Таким образом, речь идет о закрытии и воссоздании клиента каждый раз, когда вы хотите обработать сообщение, а не о том, когда вы хотите закрыть клиента, потому что вы закончили навсегда. – AndyJ

0

Вы можете остановить все сообщения не получал путем обновления подписки с:

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

Это может решите свою проблему, хотя это не совсем то, что вы просите. (Я также пытаюсь выяснить, как закрыть() должным образом.

Вам также потребуется обновить статус, чтобы начать снова получать.

Смежные вопросы