async void TryAsyncReceive(CancellationToken token, IDisposable parallelOperation) { try { using (parallelOperation) using (var context = new DefaultTransactionContext()) { var transportMessage = await ReceiveTransportMessage(token, context); if (transportMessage == null) { context.Dispose(); parallelOperation.Dispose(); _backoffStrategy.Wait(); 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 void TryReceiveNewMessage() { using (var operation = _parallelOperationsManager.TryBegin()) { // if we didn't get to do our thing, let the OS decide what to do next.... we don't hog the processor if (!operation.CanContinue()) { Thread.Yield(); return; } using (var transactionContext = new DefaultTransactionContext()) { transactionContext.Items["CancellationToken"] = _cancellationTokenSource.Token; transactionContext.Items["OwningBus"] = _owningBus; AmbientTransactionContext.Current = transactionContext; try { var result = await TryReceiveTransportMessage(transactionContext, _cancellationTokenSource.Token); if (result.Exception != null) { if (result.Exception is TaskCanceledException || result.Exception is OperationCanceledException) { // this is normal - we're being shut down so we just return quickly transactionContext.Dispose(); return; } _log.Warn("An error occurred when attempting to receive transport message: {0}", result.Exception); // error: finish the tx and wait.... transactionContext.Dispose(); await _backoffStrategy.WaitError(); return; } var message = result.TransportMessage; if (message == null) { // no message: finish the tx and wait.... await transactionContext.Complete(); transactionContext.Dispose(); await _backoffStrategy.Wait(); return; } // we got a message, so we reset the backoff strategy _backoffStrategy.Reset(); var context = new IncomingStepContext(message, transactionContext); var stagedReceiveSteps = _pipeline.ReceivePipeline(); await _pipelineInvoker.Invoke(context, stagedReceiveSteps); try { await transactionContext.Complete(); } catch (Exception exception) { _log.Error(exception, "An error occurred when attempting to complete the transaction context"); } } catch (Exception exception) { // we should not end up here unless something is off.... _log.Error(exception, "Unhandled exception in thread worker - the pipeline didn't handle its own errors (this is bad)"); Thread.Sleep(100); } finally { AmbientTransactionContext.Current = null; } } } }
public void Rollback(Enlistment enlistment) { _transactionContext.Dispose(); enlistment.Done(); }