public static AsyncAsyncSubject <TSource> GetAwaiter <TSource>(this IConnectableAsyncObservable <TSource> source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } var subject = new SequentialAsyncAsyncSubject <TSource>(); var subscribeTask = source.SubscribeSafeAsync(subject); subscribeTask.AsTask().ContinueWith(t => { if (t.Exception != null) { subject.OnErrorAsync(t.Exception); // NB: Should not occur due to use of SubscribeSafeAsync. } else { source.ConnectAsync(); } }); return(subject); }
public static AsyncAsyncSubject <TSource> RunAsync <TSource>(this IConnectableAsyncObservable <TSource> source, CancellationToken token) { if (source == null) { throw new ArgumentNullException(nameof(source)); } var subject = new SequentialAsyncAsyncSubject <TSource>(); if (token.IsCancellationRequested) { var ignored = subject.OnErrorAsync(new OperationCanceledException(token)); return(subject); } var d = new CompositeAsyncDisposable(); var subscribeTask = source.SubscribeSafeAsync(subject); subscribeTask.ContinueWith(t => { if (t.Exception != null) { subject.OnErrorAsync(t.Exception); // NB: Should not occur due to use of SubscribeSafeAsync. } else { var ignored = d.AddAsync(t.Result); source.ConnectAsync().ContinueWith(t2 => { if (t2.Exception == null) { var ignored2 = d.AddAsync(t2.Result); } }); } }); if (token.CanBeCanceled) { token.Register(() => { var ignored = d.DisposeAsync(); }); } return(subject); }
public static Task <IAsyncDisposable> AcceptAsync(this Task task, IAsyncObserver <Unit> observer, IAsyncScheduler scheduler) { if (task == null) { throw new ArgumentNullException(nameof(task)); } if (observer == null) { throw new ArgumentNullException(nameof(observer)); } if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } Task <IAsyncDisposable> CompleteAsync() { return(scheduler.ScheduleAsync(async ct => { if (ct.IsCancellationRequested) { return; } switch (task.Status) { case TaskStatus.RanToCompletion: await observer.OnNextAsync(Unit.Default).RendezVous(scheduler, ct); await observer.OnCompletedAsync().RendezVous(scheduler, ct); break; case TaskStatus.Faulted: await observer.OnErrorAsync(task.Exception.InnerException).RendezVous(scheduler, ct); break; case TaskStatus.Canceled: await observer.OnErrorAsync(new TaskCanceledException(task)).RendezVous(scheduler, ct); break; } })); } Task <IAsyncDisposable> CoreAsync() { if (task.IsCompleted) { return(CompleteAsync()); } else { var tco = TaskContinuationOptions.None; if (scheduler == ImmediateAsyncScheduler.Instance) { tco = TaskContinuationOptions.ExecuteSynchronously; } var subject = new SequentialAsyncAsyncSubject <Unit>(); task.ContinueWith(t => CompleteAsync(), tco); return(subject.SubscribeAsync(observer)); } } return(CoreAsync()); }