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

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

                    try
                    {
                        Fx.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(SRCore.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.
                    IAsyncResult result;
                    if (this.State == TransactionSignalState.Completed && Unlock(out result))
                    {
                        if (this.parent.deferredTransactionalResult != null)
                        {
                            AsyncResult.ThrowInvalidAsyncResult(this.parent.deferredTransactionalResult);
                        }
                        this.parent.deferredTransactionalResult = result;
                    }
                }
            }
Exemple #3
0
        private static void AsyncCompletionWrapperCallback(IAsyncResult result)
        {
            if (result == null)
            {
                throw Fx.Exception.AsError(new InvalidOperationException(SRCore.InvalidNullAsyncResult), null);
            }
            if (result.CompletedSynchronously)
            {
                return;
            }
            AsyncResult asyncState = (AsyncResult)result.AsyncState;

            if (asyncState.transactionContext != null && !asyncState.transactionContext.Signal(result))
            {
                return;
            }
            AsyncResult.AsyncCompletion nextCompletion = asyncState.GetNextCompletion();
            if (nextCompletion == null)
            {
                AsyncResult.ThrowInvalidAsyncResult(result);
            }
            bool      flag      = false;
            Exception exception = null;

            try
            {
                flag = nextCompletion(result);
            }
            catch (Exception exception2)
            {
                Exception exception1 = exception2;
                if (Fx.IsFatal(exception1))
                {
                    throw;
                }
                flag      = true;
                exception = exception1;
            }
            if (flag)
            {
                asyncState.Complete(false, exception);
            }
        }
Exemple #4
0
        protected IDisposable PrepareTransactionalCall(Transaction transaction)
        {
            object transactionSignalScope;

            if (this.transactionContext != null && !this.transactionContext.IsPotentiallyAbandoned)
            {
                AsyncResult.ThrowInvalidAsyncResult("PrepareTransactionalCall should only be called as the object of non-nested using statements. If the Begin succeeds, Check/SyncContinue must be called before another PrepareTransactionalCall.");
            }
            if (transaction == null)
            {
                transactionSignalScope = null;
            }
            else
            {
                transactionSignalScope = new AsyncResult.TransactionSignalScope(this, transaction);
            }
            AsyncResult.TransactionSignalScope transactionSignalScope1 = (AsyncResult.TransactionSignalScope)transactionSignalScope;
            this.transactionContext = (AsyncResult.TransactionSignalScope)transactionSignalScope;
            return(transactionSignalScope1);
        }
Exemple #5
0
            protected virtual void Dispose(bool disposing)
            {
                IAsyncResult asyncResult;

                if (disposing && !this.disposed)
                {
                    this.disposed = true;
                    if (this.State == AsyncResult.TransactionSignalState.Ready)
                    {
                        this.State = AsyncResult.TransactionSignalState.Abandoned;
                    }
                    else if (this.State != AsyncResult.TransactionSignalState.Prepared)
                    {
                        AsyncResult.ThrowInvalidAsyncResult("PrepareTransactionalCall should only be called in a using. Dispose called multiple times.");
                    }
                    else
                    {
                        this.State = AsyncResult.TransactionSignalState.Completed;
                    }
                    try
                    {
                        Fx.CompleteTransactionScope(ref this.transactionScope);
                    }
                    catch (Exception exception)
                    {
                        if (!Fx.IsFatal(exception))
                        {
                            throw Fx.Exception.AsError(new InvalidOperationException(SRCore.AsyncTransactionException), null);
                        }
                        throw;
                    }
                    if (this.State == AsyncResult.TransactionSignalState.Completed && base.Unlock(out asyncResult))
                    {
                        if (this.parent.deferredTransactionalResult != null)
                        {
                            AsyncResult.ThrowInvalidAsyncResult(this.parent.deferredTransactionalResult);
                        }
                        this.parent.deferredTransactionalResult = asyncResult;
                    }
                }
            }
Exemple #6
0
 private bool TryContinueHelper(IAsyncResult result, out AsyncResult.AsyncCompletion callback)
 {
     if (result == null)
     {
         throw Fx.Exception.AsError(new InvalidOperationException(SRCore.InvalidNullAsyncResult), null);
     }
     callback = null;
     if (!result.CompletedSynchronously)
     {
         if (!object.ReferenceEquals(result, this.deferredTransactionalResult))
         {
             return(false);
         }
         if (this.transactionContext == null || !this.transactionContext.IsSignalled)
         {
             AsyncResult.ThrowInvalidAsyncResult(result);
         }
         this.deferredTransactionalResult = null;
     }
     else if (this.transactionContext != null)
     {
         if (this.transactionContext.State != AsyncResult.TransactionSignalState.Completed)
         {
             AsyncResult.ThrowInvalidAsyncResult("Check/SyncContinue cannot be called from within the PrepareTransactionalCall using block.");
         }
         else if (this.transactionContext.IsSignalled)
         {
             AsyncResult.ThrowInvalidAsyncResult(result);
         }
     }
     callback = this.GetNextCompletion();
     if (callback == null)
     {
         AsyncResult.ThrowInvalidAsyncResult("Only call Check/SyncContinue once per async operation (once per PrepareAsyncCompletion).");
     }
     return(true);
 }