示例#1
0
            AcquireContextAsyncResult(InstanceHandle handle, Transaction hostTransaction, TimeSpan timeout, out bool setOperationPending, bool synchronous, AsyncCallback callback, object state)
                : base(callback, state)
            {
                // Need to report back to the caller whether or not we set OperationPending.
                setOperationPending = false;

                this.handle        = handle;
                HostTransaction    = hostTransaction;
                this.timeoutHelper = new TimeoutHelper(timeout);

                AcquireContextAsyncResult transactionWait;
                bool reuseContext = false;

                lock (this.handle.ThisLock)
                {
                    if (!this.handle.IsValid)
                    {
                        throw Fx.Exception.AsError(new OperationCanceledException(SRCore.HandleFreed));
                    }

                    if (this.handle.OperationPending)
                    {
                        throw Fx.Exception.AsError(new InvalidOperationException(SRCore.CommandExecutionCannotOverlap));
                    }
                    setOperationPending          = true;
                    this.handle.OperationPending = true;

                    transactionWait = this.handle.CurrentTransactionalAsyncResult;
                    if (transactionWait != null)
                    {
                        Fx.Assert(this.handle.AcquirePending == null, "Overlapped acquires pending.");

                        // If the transaction matches but is already completed (or completing), the easiest ting to do
                        // is wait for it to complete, then try to re-enlist, and have that failure be the failure mode for Execute.
                        // We do that by following the regular, non-matching transaction path.
                        if (transactionWait.HostTransaction.Equals(hostTransaction) && !this.handle.TooLateToEnlist)
                        {
                            reuseContext          = true;
                            this.executionContext = transactionWait.ReuseContext();
                            this.handle.CurrentExecutionContext = this.executionContext;
                        }
                        else
                        {
                            this.handle.AcquirePending = this;
                        }
                    }
                }

                if (transactionWait != null)
                {
                    Fx.Assert(transactionWait.IsCompleted, "Old AsyncResult must be completed by now.");

                    // Reuse the existing InstanceExecutionContext if this is the same transaction we're waiting for.
                    if (reuseContext)
                    {
                        Complete(true);
                        return;
                    }

                    TimeSpan waitTimeout = this.timeoutHelper.RemainingTime();
                    if (synchronous)
                    {
                        if (!transactionWait.WaitForHostTransaction.Wait(waitTimeout))
                        {
                            throw Fx.Exception.AsError(new TimeoutException(InternalSR.TimeoutOnOperation(waitTimeout)));
                        }
                    }
                    else
                    {
                        if (!transactionWait.WaitForHostTransaction.WaitAsync(AcquireContextAsyncResult.onHostTransaction, this, waitTimeout))
                        {
                            return;
                        }
                    }
                }

                if (DoAfterTransaction())
                {
                    Complete(true);
                }
            }
示例#2
0
 protected override void Invoke()
 {
     _callback(_state,
               this.TimedOut ? new TimeoutException(InternalSR.TimeoutOnOperation(_originalTimeout)) : null);
 }