async Task TryProcessNextMessage() { var parallelOperation = _parallelOperationsManager.TryBegin(); if (!parallelOperation.CanContinue()) { await _backoffStrategy.WaitAsync(_cancellationToken); return; } try { using (parallelOperation) using (var context = new TransactionContextWithOwningBus(_owningBus)) { var transportMessage = await ReceiveTransportMessage(_cancellationToken, context); if (transportMessage == null) { context.Dispose(); // get out quickly if we're shutting down if (_cancellationToken.IsCancellationRequested || _busDisposalCancellationToken.IsCancellationRequested) { return; } // no need for another thread to rush in and discover that there is no message //parallelOperation.Dispose(); await _backoffStrategy.WaitNoMessageAsync(_cancellationToken); return; } _backoffStrategy.Reset(); try { AmbientTransactionContext.SetCurrent(context); await ProcessMessage(context, transportMessage); } finally { AmbientTransactionContext.SetCurrent(null); } } } catch (OperationCanceledException) when(_cancellationToken.IsCancellationRequested || _busDisposalCancellationToken.IsCancellationRequested) { // we're shutting down } catch (Exception exception) { _log.Error(exception, "Unhandled exception in worker {workerName}", Name); } }