async void TryAsyncReceive(CancellationToken token, IDisposable parallelOperation) { try { using (parallelOperation) using (var context = new TransactionContext()) { var transportMessage = await ReceiveTransportMessage(token, context); if (transportMessage == null) { context.Dispose(); // no need for another thread to rush in and discover that there is no message //parallelOperation.Dispose(); _backoffStrategy.WaitNoMessage(); return; } _backoffStrategy.Reset(); await ProcessMessage(context, transportMessage); } } catch (TaskCanceledException) { // it's fine - just a sign that we are shutting down } catch (OperationCanceledException) { // it's fine - just a sign that we are shutting down } catch (Exception exception) { _log.Error(exception, "Unhandled exception in thread pool worker"); } }
async Task ProcessMessage(TransactionContext context, TransportMessage transportMessage) { try { context.Items["OwningBus"] = _owningBus; AmbientTransactionContext.SetCurrent(context); var incomingSteps = _pipeline.ReceivePipeline(); var stepContext = new IncomingStepContext(transportMessage, context); await _pipelineInvoker.Invoke(stepContext, incomingSteps); try { await context.Complete(); } catch (Exception exception) { _log.Error(exception, "An error occurred when attempting to complete the transaction context"); } } catch (ThreadAbortException exception) { context.Abort(); _log.Error(exception, $"Worker was killed while handling message {transportMessage.GetMessageLabel()}"); } catch (Exception exception) { context.Abort(); _log.Error(exception, $"Unhandled exception while handling message {transportMessage.GetMessageLabel()}"); } finally { AmbientTransactionContext.SetCurrent(null); } }
public void Dispose() { TransactionContext.Clear(); Cleanup(); }
async Task TimerElapsed() { using (var result = await _timeoutManager.GetDueMessages()) { foreach (var dueMessage in result) { var transportMessage = dueMessage.ToTransportMessage(); var returnAddress = transportMessage.Headers[Headers.DeferredRecipient]; _log.Debug("Sending due message {0} to {1}", transportMessage.Headers[Headers.MessageId], returnAddress); using (var context = new TransactionContext()) { await _transport.Send(returnAddress, transportMessage, context); await context.Complete(); } await dueMessage.MarkAsCompleted(); } await result.Complete(); } }
/// <summary> /// Constructs the context and sets itself as current in <see cref="TransactionContext"/>. /// </summary> public TxBomkarl() { TransactionContext.Set(this); threadName = Thread.CurrentThread.Name; }