static AsyncSubject <TSource> RunAsync <TSource>(IConnectableObservable <TSource> source, CancellationToken cancellationToken) { var s = new AsyncSubject <TSource>(); if (cancellationToken.IsCancellationRequested) { return(Cancel(s, cancellationToken)); } var d = source.Subscribe(s); var c = source.Connect(); if (cancellationToken.CanBeCanceled) { RegisterCancelation(s, StableCompositeDisposable.Create(d, c), cancellationToken); } return(s); }
static void RegisterCancelation <T>(AsyncSubject <T> subject, IDisposable subscription, CancellationToken token) { // // Separate method used to avoid heap allocation of closure when no cancellation is needed, // e.g. when CancellationToken.None is provided to the RunAsync overloads. // var ctr = token.Register(() => { subscription.Dispose(); Cancel(subject, token); }); // // No null-check for ctr is needed: // // - CancellationTokenRegistration is a struct // - Registration will succeed 99% of the time, no warranting an attempt to avoid spurious Subscribe calls // subject.Subscribe(Stubs <T> .Ignore, _ => ctr.Dispose(), ctr.Dispose); }
public static Func <IObservable <Unit> > ToAsync(Action action, IScheduler scheduler) { return(() => { var subject = new AsyncSubject <Unit>(); scheduler.Schedule(() => { try { action(); } catch (Exception exception) { subject.OnError(exception); return; } subject.OnNext(Unit.Default); subject.OnCompleted(); }); return subject.AsObservable(); }); }
public void Dispose() { lock (gate) { if (parent != null) { lock (parent.observerLock) { var listObserver = parent.outObserver as ListObserver <T>; if (listObserver != null) { parent.outObserver = listObserver.Remove(unsubscribeTarget); } else { parent.outObserver = EmptyObserver <T> .Instance; } unsubscribeTarget = null; parent = null; } } } }
static AsyncSubject <T> Cancel <T>(AsyncSubject <T> subject, CancellationToken cancellationToken) { subject.OnError(new OperationCanceledException(cancellationToken)); return(subject); }
public Subscription(AsyncSubject <T> parent, IObserver <T> unsubscribeTarget) { this.parent = parent; this.unsubscribeTarget = unsubscribeTarget; }