Exemple #1
0
        public static IAsyncObserver <TSource> ElementAtOrDefault <TSource>(IAsyncObserver <TSource> observer, int index)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (index < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(index));
            }

            return(Create <TSource>(
                       async x =>
            {
                if (index-- == 0)
                {
                    await observer.OnNextAsync(x).ConfigureAwait(false);
                    await observer.OnCompletedAsync().ConfigureAwait(false);
                }
            },
                       observer.OnErrorAsync,
                       async() =>
            {
                await observer.OnNextAsync(default).ConfigureAwait(false);
Exemple #2
0
        public static ValueTask <IAsyncDisposable> Timer(IAsyncObserver <long> observer, TimeSpan dueTime, IAsyncScheduler scheduler)
        {
            if (scheduler == null)
            {
                throw new ArgumentNullException(nameof(scheduler));
            }

            return(scheduler.ScheduleAsync(async ct =>
            {
                if (ct.IsCancellationRequested)
                {
                    return;
                }

                await observer.OnNextAsync(0L).RendezVous(scheduler, ct);

                if (ct.IsCancellationRequested)
                {
                    return;
                }

                await observer.OnCompletedAsync().RendezVous(scheduler, ct);
            }, dueTime));
        }
Exemple #3
0
        public static IAsyncObserver <decimal> SumDecimal(IAsyncObserver <decimal> observer)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }

            var sum = 0m;

            return(Create <decimal>(
                       x =>
            {
                sum += x;

                return Task.CompletedTask;
            },
                       observer.OnErrorAsync,
                       async() =>
            {
                await observer.OnNextAsync(sum).ConfigureAwait(false);
                await observer.OnCompletedAsync().ConfigureAwait(false);
            }
                       ));
        }
Exemple #4
0
        public static IAsyncObserver <double> SumDouble(IAsyncObserver <double> observer)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }

            var sum = 0.0;

            return(Create <double>(
                       x =>
            {
                sum += x;

                return default;
            },
                       observer.OnErrorAsync,
                       async() =>
            {
                await observer.OnNextAsync(sum).ConfigureAwait(false);
                await observer.OnCompletedAsync().ConfigureAwait(false);
            }
                       ));
        }
Exemple #5
0
        public static Task <IAsyncDisposable> Generate <TState, TResult>(IAsyncObserver <TResult> observer, TState initialState, Func <TState, Task <bool> > condition, Func <TState, Task <TState> > iterate, Func <TState, Task <TResult> > resultSelector, Func <TState, Task <DateTimeOffset> > timeSelector, IAsyncScheduler scheduler)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (condition == null)
            {
                throw new ArgumentNullException(nameof(condition));
            }
            if (iterate == null)
            {
                throw new ArgumentNullException(nameof(iterate));
            }
            if (resultSelector == null)
            {
                throw new ArgumentNullException(nameof(resultSelector));
            }
            if (timeSelector == null)
            {
                throw new ArgumentNullException(nameof(timeSelector));
            }
            if (scheduler == null)
            {
                throw new ArgumentNullException(nameof(scheduler));
            }

            return(scheduler.ScheduleAsync(async ct =>
            {
                var first = true;
                var state = initialState;

                while (!ct.IsCancellationRequested)
                {
                    var hasResult = false;
                    var result = default(TResult);
                    var nextDue = default(DateTimeOffset);

                    try
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            state = await iterate(state).RendezVous(scheduler, ct);
                        }

                        hasResult = await condition(state).RendezVous(scheduler, ct);

                        if (hasResult)
                        {
                            result = await resultSelector(state).RendezVous(scheduler, ct);
                            nextDue = await timeSelector(state).RendezVous(scheduler, ct);
                        }
                    }
                    catch (Exception ex)
                    {
                        await observer.OnErrorAsync(ex).RendezVous(scheduler, ct);
                        return;
                    }

                    if (hasResult)
                    {
                        await observer.OnNextAsync(result).RendezVous(scheduler, ct);
                    }
                    else
                    {
                        break;
                    }

                    await scheduler.Delay(nextDue).RendezVous(scheduler, ct);
                }

                if (!ct.IsCancellationRequested)
                {
                    await observer.OnCompletedAsync().RendezVous(scheduler, ct);
                }
            }));
        }
Exemple #6
0
 public Task OnCompletedAsync()
 {
     return(inner.OnCompletedAsync());
 }
Exemple #7
0
        public static (IAsyncObserver <TSource>, IAsyncObserver <TSource>) Amb <TSource>(IAsyncObserver <TSource> observer, IAsyncDisposable first, IAsyncDisposable second)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (first == null)
            {
                throw new ArgumentNullException(nameof(first));
            }
            if (second == null)
            {
                throw new ArgumentNullException(nameof(second));
            }

            var gate = new AsyncLock();

            var state = AmbState.None;

            return
                (
                Create <TSource>(
                    async x =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (state == AmbState.None)
                    {
                        state = AmbState.First;
                        await second.DisposeAsync().ConfigureAwait(false);
                    }

                    if (state == AmbState.First)
                    {
                        await observer.OnNextAsync(x).ConfigureAwait(false);
                    }
                }
            },
                    async ex =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (state == AmbState.None)
                    {
                        state = AmbState.First;
                        await second.DisposeAsync().ConfigureAwait(false);
                    }

                    if (state == AmbState.First)
                    {
                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
                    }
                }
            },
                    async() =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (state == AmbState.None)
                    {
                        state = AmbState.First;
                        await second.DisposeAsync().ConfigureAwait(false);
                    }

                    if (state == AmbState.First)
                    {
                        await observer.OnCompletedAsync().ConfigureAwait(false);
                    }
                }
            }
                    ),
                Create <TSource>(
                    async x =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (state == AmbState.None)
                    {
                        state = AmbState.Second;
                        await first.DisposeAsync().ConfigureAwait(false);
                    }

                    if (state == AmbState.Second)
                    {
                        await observer.OnNextAsync(x).ConfigureAwait(false);
                    }
                }
            },
                    async ex =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (state == AmbState.None)
                    {
                        state = AmbState.Second;
                        await first.DisposeAsync().ConfigureAwait(false);
                    }

                    if (state == AmbState.Second)
                    {
                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
                    }
                }
            },
                    async() =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (state == AmbState.None)
                    {
                        state = AmbState.Second;
                        await first.DisposeAsync().ConfigureAwait(false);
                    }

                    if (state == AmbState.Second)
                    {
                        await observer.OnCompletedAsync().ConfigureAwait(false);
                    }
                }
            }
                    )
                );
        }
Exemple #8
0
        public static IAsyncObserver <TSource>[] Amb <TSource>(IAsyncObserver <TSource> observer, IAsyncDisposable[] subscriptions)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (subscriptions == null)
            {
                throw new ArgumentNullException(nameof(subscriptions));
            }

            var gate = new AsyncLock();

            var winner = default(int?);

            var count = subscriptions.Length;

            async Task ElectWinnerAsync(int index)
            {
                winner = index;

                var dispose = new List <Task>(count - 1);

                for (var i = 0; i < count; i++)
                {
                    if (i != index)
                    {
                        dispose.Add(subscriptions[i].DisposeAsync().AsTask());
                    }
                }

                await Task.WhenAll(dispose).ConfigureAwait(false);
            }

            IAsyncObserver <TSource> CreateObserver(int index) =>
            Create <TSource>(
                async x =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (winner == null)
                    {
                        await ElectWinnerAsync(index).ConfigureAwait(false);
                    }

                    if (winner == index)
                    {
                        await observer.OnNextAsync(x).ConfigureAwait(false);
                    }
                }
            },
                async ex =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (winner == null)
                    {
                        await ElectWinnerAsync(index).ConfigureAwait(false);
                    }

                    if (winner == index)
                    {
                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
                    }
                }
            },
                async() =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (winner == null)
                    {
                        await ElectWinnerAsync(index).ConfigureAwait(false);
                    }

                    if (winner == index)
                    {
                        await observer.OnCompletedAsync().ConfigureAwait(false);
                    }
                }
            }
                );

            var res = new IAsyncObserver <TSource> [count];

            for (var i = 0; i < count; i++)
            {
                res[i] = CreateObserver(i);
            }

            return(res);
        }
 public void OnCompleted() => _observer.OnCompletedAsync().GetAwaiter().GetResult();
Exemple #10
0
            public async ValueTask Run()
            {
                await _observer.OnSubscribeAsync(this).ConfigureAwait(false);

                try
                {
                    var done = false;

                    while (true)
                    {
                        while (true)
                        {
                            if (IsCanceled)
                            {
                                return;
                            }

                            done = Volatile.Read(ref _done);

                            if (_queue.TryDequeue(out var item))
                            {
                                var t = _observer.OnNextAsync(item);

                                try
                                {
                                    await t.ConfigureAwait(false);
                                }
                                catch (Exception ex)
                                {
                                    await _observer.OnErrorAsync(ex).ConfigureAwait(false);

                                    return;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }

                        if (done)
                        {
                            break;
                        }

                        await ResumeHelper.Await(ref _tcs).ConfigureAwait(false);

                        ResumeHelper.Clear(ref _tcs);
                    }

                    if (!IsCanceled)
                    {
                        if (_error == null)
                        {
                            await _observer.OnCompletedAsync().ConfigureAwait(false);
                        }
                        else
                        {
                            await _observer.OnErrorAsync(_error).ConfigureAwait(false);
                        }
                    }

                    Dispose();
                }
                finally
                {
                    await _observer.OnFinallyAsync().ConfigureAwait(false);
                }
            }
Exemple #11
0
        public static (IAsyncObserver <TSource>, IAsyncObserver <TSource>) SequenceEqual <TSource>(IAsyncObserver <bool> observer, IEqualityComparer <TSource> comparer)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (comparer == null)
            {
                throw new ArgumentNullException(nameof(comparer));
            }

            var gate = new AsyncLock();

            var queueLeft  = new Queue <TSource>();
            var queueRight = new Queue <TSource>();
            var doneLeft   = false;
            var doneRight  = false;

            return
                (
                Create <TSource>(
                    async x =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (queueRight.Count > 0)
                    {
                        var v = queueRight.Dequeue();

                        var equal = false;
                        try
                        {
                            equal = comparer.Equals(x, v);
                        }
                        catch (Exception ex)
                        {
                            await observer.OnErrorAsync(ex).ConfigureAwait(false);
                            return;
                        }

                        if (!equal)
                        {
                            await observer.OnNextAsync(false).ConfigureAwait(false);
                            await observer.OnCompletedAsync().ConfigureAwait(false);
                        }
                    }
                    else if (doneRight)
                    {
                        await observer.OnNextAsync(false).ConfigureAwait(false);
                        await observer.OnCompletedAsync().ConfigureAwait(false);
                    }
                    else
                    {
                        queueLeft.Enqueue(x);
                    }
                }
            },
                    async ex =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    await observer.OnErrorAsync(ex).ConfigureAwait(false);
                }
            },
                    async() =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    doneLeft = true;

                    if (queueLeft.Count == 0)
                    {
                        if (queueRight.Count > 0)
                        {
                            await observer.OnNextAsync(false).ConfigureAwait(false);
                            await observer.OnCompletedAsync().ConfigureAwait(false);
                        }
                        else if (doneRight)
                        {
                            await observer.OnNextAsync(true).ConfigureAwait(false);
                            await observer.OnCompletedAsync().ConfigureAwait(false);
                        }
                    }
                }
            }
                    ),
                Create <TSource>(
                    async x =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (queueLeft.Count > 0)
                    {
                        var v = queueLeft.Dequeue();

                        var equal = false;
                        try
                        {
                            equal = comparer.Equals(v, x);
                        }
                        catch (Exception ex)
                        {
                            await observer.OnErrorAsync(ex).ConfigureAwait(false);
                            return;
                        }

                        if (!equal)
                        {
                            await observer.OnNextAsync(false).ConfigureAwait(false);
                            await observer.OnCompletedAsync().ConfigureAwait(false);
                        }
                    }
                    else if (doneLeft)
                    {
                        await observer.OnNextAsync(false).ConfigureAwait(false);
                        await observer.OnCompletedAsync().ConfigureAwait(false);
                    }
                    else
                    {
                        queueRight.Enqueue(x);
                    }
                }
            },
                    async ex =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    await observer.OnErrorAsync(ex).ConfigureAwait(false);
                }
            },
                    async() =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    doneRight = true;

                    if (queueRight.Count == 0)
                    {
                        if (queueLeft.Count > 0)
                        {
                            await observer.OnNextAsync(false).ConfigureAwait(false);
                            await observer.OnCompletedAsync().ConfigureAwait(false);
                        }
                        else if (doneLeft)
                        {
                            await observer.OnNextAsync(true).ConfigureAwait(false);
                            await observer.OnCompletedAsync().ConfigureAwait(false);
                        }
                    }
                }
            }
                    )
                );
        }
Exemple #12
0
 public Task CompleteStream()
 {
     return(observer == null ? TaskDone.Done : observer.OnCompletedAsync());
 }
Exemple #13
0
        public static (IAsyncObserver <TFirst>, IAsyncObserver <TSecond>) WithLatestFrom <TFirst, TSecond, TResult>(IAsyncObserver <TResult> observer, Func <TFirst, TSecond, ValueTask <TResult> > resultSelector)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (resultSelector == null)
            {
                throw new ArgumentNullException(nameof(resultSelector));
            }

            var gate = new AsyncLock();

            async ValueTask OnErrorAsync(Exception ex)
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    await observer.OnErrorAsync(ex).ConfigureAwait(false);
                }
            }

            var hasLatest = false;
            var latest    = default(TSecond);

            return
                (
                Create <TFirst>(
                    async x =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (hasLatest)
                    {
                        var res = default(TResult);

                        try
                        {
                            res = await resultSelector(x, latest).ConfigureAwait(false);
                        }
                        catch (Exception ex)
                        {
                            await observer.OnErrorAsync(ex).ConfigureAwait(false);
                            return;
                        }

                        await observer.OnNextAsync(res).ConfigureAwait(false);
                    }
                }
            },
                    OnErrorAsync,
                    async() =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    await observer.OnCompletedAsync().ConfigureAwait(false);
                }
            }
                    ),
                Create <TSecond>(
                    async y =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    hasLatest = true;
                    latest = y;
                }
            },
                    OnErrorAsync,
                    () => default
                    )
                );
        }
Exemple #14
0
        public static IAsyncObserver <TSource> Buffer <TSource>(IAsyncObserver <IList <TSource> > observer, int count, int skip)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (count <= 0)
            {
                throw new ArgumentNullException(nameof(count));
            }
            if (skip <= 0)
            {
                throw new ArgumentNullException(nameof(skip));
            }

            var queue = new Queue <IList <TSource> >();
            var n     = 0;

            void CreateBuffer() => queue.Enqueue(new List <TSource>());

            CreateBuffer();

            return(Create <TSource>(
                       async x =>
            {
                foreach (var buffer in queue)
                {
                    buffer.Add(x);
                }

                var c = n - count + 1;

                if (c >= 0 && c % skip == 0)
                {
                    var buffer = queue.Dequeue();

                    if (buffer.Count > 0)
                    {
                        await observer.OnNextAsync(buffer).ConfigureAwait(false);
                    }
                }

                n++;

                if (n % skip == 0)
                {
                    CreateBuffer();
                }
            },
                       ex =>
            {
                while (queue.Count > 0)
                {
                    queue.Dequeue().Clear();
                }

                return observer.OnErrorAsync(ex);
            },
                       async() =>
            {
                while (queue.Count > 0)
                {
                    var buffer = queue.Dequeue();

                    if (buffer.Count > 0)
                    {
                        await observer.OnNextAsync(buffer).ConfigureAwait(false);
                    }
                }

                await observer.OnCompletedAsync().ConfigureAwait(false);
            }
                       ));
        }
 public Task OnCompletedAsync() => _observer.OnCompletedAsync();
Exemple #16
0
        public static IAsyncObserver <TSource> MinBy <TSource, TKey>(IAsyncObserver <IList <TSource> > observer, Func <TSource, Task <TKey> > keySelector, IComparer <TKey> comparer)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (keySelector == null)
            {
                throw new ArgumentNullException(nameof(keySelector));
            }
            if (comparer == null)
            {
                throw new ArgumentNullException(nameof(comparer));
            }

            var hasValue = false;
            var lastKey  = default(TKey);
            var list     = new List <TSource>();

            return(Create <TSource>(
                       async x =>
            {
                var key = default(TKey);
                try
                {
                    key = await keySelector(x).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    await observer.OnErrorAsync(ex).ConfigureAwait(false);
                    return;
                }

                var comparison = 0;

                if (!hasValue)
                {
                    hasValue = true;
                    lastKey = key;
                }
                else
                {
                    try
                    {
                        comparison = comparer.Compare(key, lastKey);
                    }
                    catch (Exception ex)
                    {
                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
                        return;
                    }
                }

                if (comparison < 0)
                {
                    lastKey = key;
                    list.Clear();
                }

                if (comparison <= 0)
                {
                    list.Add(x);
                }
            },
                       observer.OnErrorAsync,
                       async() =>
            {
                await observer.OnNextAsync(list).ConfigureAwait(false);
                await observer.OnCompletedAsync().ConfigureAwait(false);
            }
                       ));
        }
Exemple #17
0
        public static (IAsyncObserver <TSource>, IAsyncObserver <TSample>) Sample <TSource, TSample>(IAsyncObserver <TSource> observer)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }

            var gate = new AsyncLock();

            var hasValue = false;
            var value    = default(TSource);
            var atEnd    = false;

            async ValueTask OnSampleAsync()
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (hasValue)
                    {
                        hasValue = false;
                        await observer.OnNextAsync(value).ConfigureAwait(false);
                    }

                    if (atEnd)
                    {
                        await observer.OnCompletedAsync().ConfigureAwait(false);
                    }
                }
            }

            return
                (
                Create <TSource>(
                    async x =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    hasValue = true;
                    value = x;
                }
            },
                    async ex =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    await observer.OnErrorAsync(ex).ConfigureAwait(false);
                }
            },
                    async() =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    atEnd = true;
                }
            }
                    ),
                Create <TSample>(
                    _ => OnSampleAsync(),
                    async ex =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    await observer.OnErrorAsync(ex).ConfigureAwait(false);
                }
            },
                    OnSampleAsync
                    )
                );
        }
Exemple #18
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());
        }
Exemple #19
0
        public static IAsyncObserver <TSource>[] Zip <TSource>(IAsyncObserver <IList <TSource> > observer, int count)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            var gate = new AsyncLock();

            var queues = new Queue <TSource> [count];
            var isDone = new bool[count];
            var res    = new IAsyncObserver <TSource> [count];

            IAsyncObserver <TSource> CreateObserver(int index) =>
            Create <TSource>(
                async x =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    queues[index].Enqueue(x);

                    if (queues.All(queue => queue.Count > 0))
                    {
                        var list = new TSource[count];

                        for (var i = 0; i < count; i++)
                        {
                            list[i] = queues[i].Dequeue();
                        }

                        await observer.OnNextAsync(list).ConfigureAwait(false);
                    }
                    else
                    {
                        var allDone = true;

                        for (var i = 0; i < count; i++)
                        {
                            if (i != index && !isDone[i])
                            {
                                allDone = false;
                                break;
                            }
                        }

                        if (allDone)
                        {
                            await observer.OnCompletedAsync().ConfigureAwait(false);
                        }
                    }
                }
            },
                async ex =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    await observer.OnErrorAsync(ex).ConfigureAwait(false);
                }
            },
                async() =>
            {
                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    isDone[index] = true;

                    var allDone = true;

                    for (var i = 0; i < count; i++)
                    {
                        if (!isDone[i])
                        {
                            allDone = false;
                            break;
                        }
                    }

                    if (allDone)
                    {
                        await observer.OnCompletedAsync().ConfigureAwait(false);
                    }
                }
            }
                );

            for (var i = 0; i < count; i++)
            {
                queues[i] = new Queue <TSource>();
                res[i]    = CreateObserver(i);
            }

            return(res);
        }
        protected async Task RunAsync(CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                var values = default(T[]);
                var error  = default(Exception);
                var done   = false;

                using (await RendezVous(_lock.LockAsync()))
                {
                    if (_queue.Count > 0)
                    {
                        values = _queue.ToArray();
                        _queue.Clear();
                    }

                    if (_done)
                    {
                        done  = _done;
                        error = _error;
                    }

                    if (values == null && !done)
                    {
                        _busy = false;
                        break;
                    }
                }

                try
                {
                    if (values != null)
                    {
                        foreach (var value in values)
                        {
                            await RendezVous(_observer.OnNextAsync(value));
                        }
                    }

                    if (done)
                    {
                        if (error != null)
                        {
                            await RendezVous(_observer.OnErrorAsync(error));
                        }
                        else
                        {
                            await RendezVous(_observer.OnCompletedAsync());
                        }

                        break;
                    }
                }
                catch
                {
                    using (await RendezVous(_lock.LockAsync()))
                    {
                        _hasFaulted = true;
                        _queue.Clear();
                    }

                    throw;
                }
            }
        }
Exemple #21
0
 public async Task OnCompletedAsync()
 {
     await _observer.OnCompletedAsync();
 }