Esempio n. 1
0
        public static Progressor <T> CreateDistinct(Progressor <T> wrapped)
        {
            if (wrapped == null)
            {
                throw new ArgumentNullException("wrapped");
            }

            var control = 0;

            SafeDictionary <T, bool> buffer    = new SafeDictionary <T, bool>();
            Predicate <T>            newFilter = item => Thread.VolatileRead(ref control) == 0;
            var proxy = new ProxyObservable <T>();

            Progressor <T> result = new Progressor <T>(
                (out T value) =>
            {
                Interlocked.Increment(ref control);
                try
                {
                    again:
                    foreach (KeyValuePair <T, bool> item in buffer)
                    {
                        if (!item.Value)
                        {
                            value = item.Key;
                            buffer.Set(value, true);
                            proxy.OnNext(value);
                            return(true);
                        }
                    }
                    if (wrapped.TryTake(out value))
                    {
                        bool seen;
                        if (!buffer.TryGetValue(value, out seen) || !seen)
                        {
                            buffer.Set(value, true);
                            proxy.OnNext(value);
                            return(true);
                        }
                        else
                        {
                            goto again;
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                finally
                {
                    Interlocked.Decrement(ref control);
                }
            },
                proxy
                );

            wrapped.Subscribe
            (
                new CustomObserver <T>
                (
                    () => result._done        = true,
                    exception => result._done = true,
                    item =>
            {
                if (newFilter(item))
                {
                    buffer.TryAdd(item, false);
                }
            }
                )
            );
            return(result);
        }
Esempio n. 2
0
        public static Progressor <T> CreatedFilteredConverted <TInput>(Progressor <TInput> wrapped, Predicate <TInput> filter, Converter <TInput, T> converter)
        {
            if (wrapped == null)
            {
                throw new ArgumentNullException("wrapped");
            }
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }
            if (converter == null)
            {
                throw new ArgumentNullException("converter");
            }

            var control = 0;

            Predicate <TInput> newFilter = item => Thread.VolatileRead(ref control) == 0 && filter(item);
            var buffer = new SafeQueue <T>();
            var proxy  = new ProxyObservable <T>();

            var result = new Progressor <T>(
                (out T value) =>
            {
                Interlocked.Increment(ref control);
                try
                {
                    TInput item;
                    again:
                    if (buffer.TryTake(out value))
                    {
                        proxy.OnNext(value);
                        return(true);
                    }
                    else if (wrapped.TryTake(out item))
                    {
                        if (filter(item))
                        {
                            value = converter(item);
                            proxy.OnNext(value);
                            return(true);
                        }
                        else
                        {
                            goto again;
                        }
                    }
                    value = default(T);
                    return(false);
                }
                finally
                {
                    Interlocked.Decrement(ref control);
                }
            },
                proxy
                );

            wrapped.Subscribe
            (
                new CustomObserver <TInput>
                (
                    () => result._done        = true,
                    exception => result._done = true,
                    item =>
            {
                if (newFilter(item))
                {
                    buffer.Add(converter(item));
                }
            }
                )
            );
            return(result);
        }