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
                                         ));
        }