private Lazy <ServiceBusClient> CreateSessionClient() { return(new Lazy <ServiceBusClient>(() => _messagingProvider.CreateSessionClient(_serviceBusAccount.ConnectionString))); }
internal void StartMessageBatchReceiver(CancellationToken cancellationToken) { SessionClient sessionClient = null; IMessageReceiver receiver = null; if (_isSessionsEnabled) { sessionClient = _messagingProvider.CreateSessionClient(_entityPath, _serviceBusAccount.ConnectionString); } else { receiver = Receiver; } Task.Run(async() => { while (true) { try { if (!_started || cancellationToken.IsCancellationRequested) { return; } if (_isSessionsEnabled) { try { receiver = await sessionClient.AcceptMessageSessionAsync(); } catch (ServiceBusTimeoutException) { // it's expected if the entity is empty, try next time continue; } } IList <Message> messages = await receiver.ReceiveAsync(_serviceBusOptions.BatchOptions.MaxMessageCount, _serviceBusOptions.BatchOptions.OperationTimeout); if (messages != null) { Message[] messagesArray = messages.ToArray(); ServiceBusTriggerInput input = ServiceBusTriggerInput.CreateBatch(messagesArray); input.MessageReceiver = receiver; FunctionResult result = await _triggerExecutor.TryExecuteAsync(input.GetTriggerFunctionData(), cancellationToken); if (cancellationToken.IsCancellationRequested) { return; } // Complete batch of messages only if the execution was successful if (_serviceBusOptions.BatchOptions.AutoComplete && _started) { if (result.Succeeded) { await receiver.CompleteAsync(messagesArray.Select(x => x.SystemProperties.LockToken)); } else { // Delivery count is not incremented if // Session is accepted, the messages within the session are not completed (even if they are locked), and the session is closed // https://docs.microsoft.com/en-us/azure/service-bus-messaging/message-sessions#impact-of-delivery-count if (_isSessionsEnabled) { List <Task> abandonTasks = new List <Task>(); foreach (var lockTocken in messagesArray.Select(x => x.SystemProperties.LockToken)) { abandonTasks.Add(receiver.AbandonAsync(lockTocken)); } await Task.WhenAll(abandonTasks); } } } // Close the session and release the session lock if (_isSessionsEnabled) { await receiver.CloseAsync(); } } } catch (ObjectDisposedException) { // Ignore as we are stopping the host } catch (Exception ex) { // Log another exception _logger.LogError($"An unhandled exception occurred in the message batch receive loop: {ex.ToString()}"); } } }, cancellationToken); }