Beispiel #1
0
            void IDisposable.Dispose()
            {
                if (State == TransactionSignalState.Ready)
                {
                    State = TransactionSignalState.Abandoned;
                }
                else if (State == TransactionSignalState.Prepared)
                {
                    State = TransactionSignalState.Completed;
                }
                else
                {
                    AsyncResult.ThrowInvalidAsyncResult("PrepareTransactionalCall should only be called in a using. Dispose called multiple times.");
                }

                try
                {
                    TransactionHelper.CompleteTransactionScope(ref this.transactionScope);
                }
                catch (Exception exception)
                {
                    if (Fx.IsFatal(exception))
                    {
                        throw;
                    }

                    // Complete and Dispose are not expected to throw.  If they do it can mess up the AsyncResult state machine.
                    throw Fx.Exception.AsError(new InvalidOperationException(SR.AsyncTransactionException));
                }

                // This will release the callback to run, or tell us that we need to defer the callback to Check/SyncContinue.
                //
                // It's possible to avoid this Interlocked when CompletedSynchronously is true, but we have no way of knowing that
                // from here, and adding a way would add complexity to the AsyncResult transactional calling pattern. This
                // unnecessary Interlocked only happens when: PrepareTransactionalCall is called with a non-null transaction,
                // PrepareAsyncCompletion is reached, and the operation completes synchronously or with an exception.
                if (State == TransactionSignalState.Completed && Unlock(out var result))
                {
                    if (this.parent.deferredTransactionalResult != null)
                    {
                        AsyncResult.ThrowInvalidAsyncResult(this.parent.deferredTransactionalResult);
                    }
                    this.parent.deferredTransactionalResult = result;
                }
            }
Beispiel #2
0
 void IExecutionProperty.CleanupWorkflowThread()
 {
     TransactionHelper.CompleteTransactionScope(ref this.scope);
 }