public IObservable <T> Use <T>(Func <IDatabaseConnection, CancellationToken, IEnumerable <T> > f) { Contract.Requires(f != null); if (disposed) { throw new ObjectDisposedException(this.GetType().FullName); } return(Observable.Create((IObserver <T> observer, CancellationToken cancellationToken) => { // Prevent calls to subscribe after the connection is disposed if (this.disposed) { observer.OnError(new ObjectDisposedException(this.GetType().FullName)); return Task.FromResult(Unit.Default); } return queue.EnqueueOperation(ct => { this.progressHandlerResult.Value = false; var ctSubscription = ct.Register(() => this.progressHandlerResult.Value = true); try { ct.ThrowIfCancellationRequested(); // Note: Diposing the connection wrapper doesn't dispose the underlying connection // The intent here is to prevent access to the underlying connection outside of the // function call. using (var db = new DelegatingDatabaseConnection(this.conn)) { foreach (var e in f(db, ct)) { observer.OnNext(e); ct.ThrowIfCancellationRequested(); } observer.OnCompleted(); } } finally { ctSubscription.Dispose(); this.progressHandlerResult.Value = false; } }, scheduler, cancellationToken); })); }
public static Task EnqueueOperation(this OperationsQueue This, Action <CancellationToken> calculationFunc, IScheduler scheduler, CancellationToken cancellationToken) => This.EnqueueOperation(ct => Observable.Start(() => calculationFunc(ct), scheduler).ToTask(), cancellationToken);