Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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());
        }