示例#1
0
 public void Prepared()
 {
     if (State != TransactionSignalState.Ready)
     {
         ThrowInvalidAsyncResult("PrepareAsyncCompletion should only be called once per PrepareTransactionalCall.");
     }
     State = TransactionSignalState.Prepared;
 }
示例#2
0
            protected virtual void Dispose(bool disposing)
            {
                if (disposing && !_disposed)
                {
                    _disposed = true;

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

                    try
                    {
                        Fx.CompleteTransactionScope(ref _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(CommonResources.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 IAsyncResult result))
                    {
                        if (_parent._deferredTransactionalResult != null)
                        {
                            ThrowInvalidAsyncResult(_parent._deferredTransactionalResult);
                        }
                        _parent._deferredTransactionalResult = result;
                    }
                }
            }