public void Prepared() { if (State != TransactionSignalState.Ready) { AsyncResult.ThrowInvalidAsyncResult("PrepareAsyncCompletion should only be called once per PrepareTransactionalCall."); } this.State = TransactionSignalState.Prepared; }
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; } } }
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); } }
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); }
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; } } }
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); }