예제 #1
0
        public void ObservableProgressor()
        {
            var source = Progressor <int> .CreateFromArray(new[] { 0, 1, 2, 3, 4, 5 });

            var progressor = Progressor <int> .CreateFromIObservable(source);

            source.Consume();
            var indexA = 0;
            var indexB = 0;

            using
            (
                progressor.SubscribeAction
                (
                    value =>
            {
                Assert.AreEqual(value, indexB);
                indexB++;
            }
                )
            )
            {
                while (progressor.TryTake(out var item))
                {
                    Assert.AreEqual(item, indexA);
                    indexA++;
                }
                Assert.AreEqual(6, indexA);
                Assert.AreEqual(indexA, indexB);
            }
        }
예제 #2
0
        public void ObservableProgressorWithPause()
        {
            var source     = new SlowObservable <int>(new[] { 0, 1, 2, 3, 4, 5 });
            var progressor = Progressor <int> .CreateFromIObservable(source);

            Assert.IsFalse(progressor.IsClosed);
            var data = new[] { 0, 0, 0 };

            using
            (
                progressor.SubscribeAction
                (
                    value =>
            {
                if (value != Volatile.Read(ref data[0]))
                {
                    Volatile.Write(ref data[2], 1);
                }

                Interlocked.Increment(ref data[0]);
            }
                )
            )
            {
#if TARGETS_NET
                Thread.MemoryBarrier();
                Thread.MemoryBarrier();
#else
                Interlocked.MemoryBarrier();
                Interlocked.MemoryBarrier();
#endif
                source.Show();
#if TARGETS_NET
                Thread.MemoryBarrier();
#else
                Interlocked.MemoryBarrier();
#endif
                while (progressor.TryTake(out var item))
                {
                    Assert.AreEqual(0, Volatile.Read(ref data[2]));
                    Assert.AreEqual(item, Volatile.Read(ref data[1]));
                    Interlocked.Increment(ref data[1]);
                }

                if (Volatile.Read(ref data[0]) != 6 || Volatile.Read(ref data[1]) != 6)
                {
                    Debugger.Break();
                }
            }

            Assert.AreEqual(6, Volatile.Read(ref data[0]));
            Assert.AreEqual(Volatile.Read(ref data[0]), Volatile.Read(ref data[1]));
            Assert.IsTrue(progressor.IsClosed);
        }
예제 #3
0
        private bool MoveNext()
        {
            TSource item;

            if (_enumerator == null)
            {
                return(false);
            }

            lock (_enumerator)
            {
                if (!_enumerator.MoveNext())
                {
                    _enumerator.Dispose();
                    _cancellationTokenSource.Cancel();
                    _enumerator = null;
                    return(false);
                }

                item = _enumerator.Current;
            }

            var key     = _keySelector(item);
            var element = _resultSelector(item);

            if (_proxies.TryGetOrAdd(key, _ => new ProxyObservable <TElement>(), out var proxy))
            {
                var progressor = Progressor <TElement> .CreateFromIObservable
                                 (
                    proxy,
                    Advance,
                    _cancellationTokenSource.Token
                                 );

                var items = ProgressiveCollection <TElement> .Create
                            (
                    progressor,
                    new ThreadSafeCollection <TElement>(),
                    EqualityComparer <TElement> .Default
                            );

                var result = new Grouping <TKey, TElement>(key, items);
                _results.Add(result);
            }

            proxy.OnNext(element);
            return(true);
        }