Beispiel #1
0
        public static IAsyncObservable <TSource> While <TSource>(Func <Task <bool> > condition, IAsyncObservable <TSource> source)
        {
            if (condition == null)
            {
                throw new ArgumentNullException(nameof(condition));
            }
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(Create <TSource>(async observer =>
            {
                var subscription = new SerialAsyncDisposable();

                var o = default(IAsyncObserver <TSource>);

                o = AsyncObserver.CreateUnsafe <TSource>(
                    observer.OnNextAsync,
                    observer.OnErrorAsync,
                    MoveNext
                    );

                async ValueTask MoveNext()
                {
                    var b = default(bool);

                    try
                    {
                        b = await condition().ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
                        return;
                    }

                    if (b)
                    {
                        var sad = new SingleAssignmentAsyncDisposable();
                        await subscription.AssignAsync(sad).ConfigureAwait(false);

                        var d = await source.SubscribeSafeAsync(o).ConfigureAwait(false);
                        await sad.AssignAsync(d).ConfigureAwait(false);
                    }
                    else
                    {
                        await observer.OnCompletedAsync().ConfigureAwait(false);
                    }
                }

                await MoveNext().ConfigureAwait(false);

                return subscription;
            }));
        }
Beispiel #2
0
        public static IAsyncObservable <TSource> SubscribeOn <TSource>(this IAsyncObservable <TSource> source, IAsyncScheduler subscribeScheduler, IAsyncScheduler disposeScheduler)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (subscribeScheduler == null)
            {
                throw new ArgumentNullException(nameof(subscribeScheduler));
            }
            if (disposeScheduler == null)
            {
                throw new ArgumentNullException(nameof(disposeScheduler));
            }

            return(CreateAsyncObservable <TSource> .From(
                       source,
                       (subscribeScheduler, disposeScheduler),
                       static async (source, state, observer) =>
            {
                var m = new SingleAssignmentAsyncDisposable();
                var d = new SerialAsyncDisposable();

                await d.AssignAsync(m).ConfigureAwait(false);

                var scheduled = await state.subscribeScheduler.ScheduleAsync(async ct =>
                {
                    var subscription = await source.SubscribeSafeAsync(observer).RendezVous(state.subscribeScheduler, ct);

                    var scheduledDispose = AsyncDisposable.Create(async() =>
                    {
                        await state.disposeScheduler.ScheduleAsync(async _ =>
                        {
                            await subscription.DisposeAsync().RendezVous(state.disposeScheduler, ct);
                        }).ConfigureAwait(false);
                    });

                    await d.AssignAsync(scheduledDispose).RendezVous(state.subscribeScheduler, ct);
                }).ConfigureAwait(false);

                await m.AssignAsync(scheduled).ConfigureAwait(false);

                return d;
            }));
        }
Beispiel #3
0
        public static IAsyncObservable <TResult> For <TSource, TResult>(IEnumerable <TSource> source, Func <TSource, Task <IAsyncObservable <TResult> > > resultSelector)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (resultSelector == null)
            {
                throw new ArgumentNullException(nameof(resultSelector));
            }

            return(Create <TResult>(async observer =>
            {
                var subscription = new SerialAsyncDisposable();

                var enumerator = source.GetEnumerator();

                var o = default(IAsyncObserver <TResult>);

                o = AsyncObserver.CreateUnsafe <TResult>(
                    observer.OnNextAsync,
                    observer.OnErrorAsync,
                    MoveNext
                    );

                async Task MoveNext()
                {
                    var b = default(bool);
                    var next = default(IAsyncObservable <TResult>);

                    try
                    {
                        b = enumerator.MoveNext();

                        if (b)
                        {
                            next = await resultSelector(enumerator.Current).ConfigureAwait(false);
                        }
                    }
                    catch (Exception ex)
                    {
                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
                        return;
                    }

                    if (b)
                    {
                        var sad = new SingleAssignmentAsyncDisposable();
                        await subscription.AssignAsync(sad).ConfigureAwait(false);

                        var d = await next.SubscribeSafeAsync(o).ConfigureAwait(false);
                        await sad.AssignAsync(d).ConfigureAwait(false);
                    }
                    else
                    {
                        await observer.OnCompletedAsync().ConfigureAwait(false);
                    }
                }

                await MoveNext().ConfigureAwait(false);

                var disposeEnumerator = AsyncDisposable.Create(() =>
                {
                    enumerator.Dispose();
                    return Task.CompletedTask;
                });

                return StableCompositeAsyncDisposable.Create(disposeEnumerator, subscription);
            }));
        }