private Task ForkCase(IInvocation invocation, ICreatedTransaction txData) { Contract.Requires(txData.Transaction.State == TransactionState.Active); Contract.Ensures(Contract.Result<Task>() != null); Contract.Assume(txData.Transaction.Inner is DependentTransaction); if (_Logger.IsDebugEnabled) _Logger.DebugFormat("fork case"); return Task.Factory.StartNew(t => { var hasException = false; var tuple = (Tuple<IInvocation, ICreatedTransaction, string>)t; var dependent = tuple.Item2.Transaction.Inner as DependentTransaction; using (tuple.Item2.GetForkScope()) try { if (_Logger.IsDebugEnabled) _Logger.DebugFormat("calling proceed on tx#{0}", tuple.Item3); using (var ts = new TransactionScope(dependent)) { tuple.Item1.Proceed(); if (_Logger.IsDebugEnabled) _Logger.DebugFormat("calling complete on TransactionScope for tx#{0}", tuple.Item3); ts.Complete(); } } catch (TransactionAbortedException ex) { // if we have aborted the transaction, we both warn and re-throw the exception hasException = true; if (_Logger.IsWarnEnabled) _Logger.Warn("transaction aborted", ex); throw new TransactionAbortedException( "Parallel/forked transaction aborted! See inner exception for details.", ex); } catch (Exception) { hasException = true; throw; } finally { if (_Logger.IsDebugEnabled) _Logger.Debug("in finally-clause, completing dependent if it didn't throw exception"); if (!hasException) dependent.Complete(); if (Finally != null) Finally.Set(); // See footnote at end of file } }, Tuple.Create(invocation, txData, txData.Transaction.LocalIdentifier)); }
private Task ForkCase(IInvocation invocation, ICreatedTransaction txData) { Contract.Requires(txData.Transaction.State == TransactionState.Active); Contract.Ensures(Contract.Result <Task>() != null); Contract.Assume(txData.Transaction.Inner is DependentTransaction); if (_Logger.IsDebugEnabled) { _Logger.DebugFormat("fork case"); } return(Task.Factory.StartNew(t => { var hasException = false; var tuple = (Tuple <IInvocation, ICreatedTransaction, string>)t; var dependent = tuple.Item2.Transaction.Inner as DependentTransaction; using (tuple.Item2.GetForkScope()) { try { _Logger.Debug(() => string.Format("calling proceed on tx#{0}", tuple.Item3)); using (var ts = new TransactionScope(dependent)) { tuple.Item1.Proceed(); _Logger.Debug(() => string.Format("calling complete on TransactionScope for tx#{0}", tuple.Item3)); ts.Complete(); } } catch (TransactionAbortedException ex) { // if we have aborted the transaction, we both warn and re-throw the exception hasException = true; if (_Logger.IsWarnEnabled) { _Logger.Warn("transaction aborted", ex); } throw new TransactionAbortedException( "Parallel/forked transaction aborted! See inner exception for details.", ex); } catch (Exception) { hasException = true; throw; } finally { if (_Logger.IsDebugEnabled) { _Logger.Debug("in finally-clause, completing dependent if it didn't throw exception"); } if (!hasException) { dependent.Complete(); } if (Finally != null) { Finally.Set(); } // See footnote at end of file } } }, Tuple.Create(invocation, txData, txData.Transaction.LocalIdentifier))); }
private Task ForkCase(IInvocation invocation, ICreatedTransaction txData) { Contract.Requires(txData.Transaction.State == TransactionState.Active); Contract.Ensures(Contract.Result <Task>() != null); Contract.Assume(txData.Transaction.Inner is DependentTransaction); if (_Logger.IsEnabled(LogLevel.Debug)) { _Logger.LogDebug("fork case"); } return(Task.Factory.StartNew(t => { var hasException = false; var tuple = (Tuple <IInvocation, ICreatedTransaction, string>)t; var dependent = tuple.Item2.Transaction.Inner as DependentTransaction; using (tuple.Item2.GetForkScope()) { try { if (_Logger.IsEnabled(LogLevel.Debug)) { _Logger.LogDebug($"calling proceed on tx#{tuple.Item3}"); } using (var ts = new TransactionScope(dependent)) { tuple.Item1.Proceed(); if (_Logger.IsEnabled(LogLevel.Debug)) { _Logger.LogDebug($"calling complete on TransactionScope for tx#{tuple.Item3}"); } ts.Complete(); } } catch (TransactionAbortedException ex) { // if we have aborted the transaction, we both warn and re-throw the exception hasException = true; if (_Logger.IsEnabled(LogLevel.Warning)) { _Logger.LogWarning(ex, "transaction aborted"); } throw new TransactionAbortedException( "Parallel/forked transaction aborted! See inner exception for details.", ex); } catch (Exception ex) { hasException = true; if (_Logger.IsEnabled(LogLevel.Debug)) { _Logger.LogDebug(ex, ex.Message); } throw; } finally { if (_Logger.IsEnabled(LogLevel.Debug)) { _Logger.LogDebug("in finally-clause, completing dependent if it didn't throw exception"); } if (!hasException) { dependent.Complete(); } Finally?.Set(); // See footnote at end of file } } }, Tuple.Create(invocation, txData, txData.Transaction.LocalIdentifier), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default )); }