Esempio 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);
        }
Esempio 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);
        }
Esempio n. 3
0
        public static IAsyncObservable <TSource> RefCount <TSource>(this IConnectableAsyncObservable <TSource> source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            var gate        = new AsyncLock();
            var count       = 0;
            var connectable = default(IAsyncDisposable);

            return(Create <TSource>(async observer =>
            {
                var subscription = await source.SubscribeSafeAsync(observer).ConfigureAwait(false);

                using (await gate.LockAsync().ConfigureAwait(false))
                {
                    if (++count == 1)
                    {
                        connectable = await source.ConnectAsync().ConfigureAwait(false);
                    }
                }

                return AsyncDisposable.Create(async() =>
                {
                    await subscription.DisposeAsync().ConfigureAwait(false);

                    using (await gate.LockAsync().ConfigureAwait(false))
                    {
                        if (--count == 0)
                        {
                            await connectable.DisposeAsync().ConfigureAwait(false);
                        }
                    }
                });
            }));
        }