private async Task DisposeStatementAsync(ReservedForStatement reservationObject) { try { await this.UseStreamWithinStatementAsync(reservationObject, async() => await this.PerformDisposeStatementAsync(reservationObject)); } finally { Interlocked.Exchange(ref this._currentlyExecutingStatement, NotInUse.Instance); } }
private async Task UseStreamOutsideStatementAsync(Func <Task> action, ReservedForStatement reservedState, Boolean oneTimeOnly) { if (ReferenceEquals(Interlocked.CompareExchange(ref this._currentlyExecutingStatement, reservedState, NotInUse.Instance), NotInUse.Instance)) { try { await this.UseStreamWithinStatementAsync(reservedState, action); } finally { if (oneTimeOnly) { Interlocked.Exchange(ref this._currentlyExecutingStatement, NotInUse.Instance); } } } else { throw new InvalidOperationException("The connection is currently being used by another statement."); } }
public async Task <T> UseStreamWithinStatementAsync <T>(ReservedForStatement reservedState, Func <Task <T> > action) { ArgumentValidator.ValidateNotNull(nameof(reservedState), reservedState); ConnectionStreamUsageState prevState; if (ReferenceEquals((prevState = Interlocked.CompareExchange(ref this._currentlyExecutingStatement, reservedState.UsageState, reservedState)), reservedState) || // Transition ReferenceEquals(prevState, reservedState.UsageState) // Re-entrance ) { try { return(await action()); } finally { Interlocked.Exchange(ref this._currentlyExecutingStatement, prevState); } } else { throw new InvalidOperationException("The stream is not reserved for this statement."); } }
protected abstract Task <(TEnumerableItem, MoveNextAsyncDelegate <TEnumerableItem>)> ExecuteStatement(TStatement stmt, ReservedForStatement reservationObject);
protected abstract Task PerformDisposeStatementAsync(ReservedForStatement reservationObject);