예제 #1
0
        // The callers (Last/LastOrDefault) are blocking methods.
        static TSource InternalLastOrDefault <TSource> (this IObservable <TSource> source, Func <TSource, bool> predicate, bool throwError)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (predicate == null)
            {
                throw new ArgumentNullException("predicate");
            }

            var     wait = new HybridWait();
            TSource ret  = default(TSource);
            bool    got  = false;
            var     dis  = source.Subscribe(
                // the first "if (!got) check is required because the source may send next values before unsubscribing this action by dis.Dispose().
                (s) => { if (predicate(s))
                         {
                             got = true; ret = s;
                         }
                },
                () => { wait.Set(); }
                );

            wait.WaitOne();
            dis.Dispose();
            if (!got && throwError)
            {
                throw new InvalidOperationException();
            }
            return(ret);
        }
예제 #2
0
        // The callers (Single/SingleOrDefault) are blocking methods.
        static TSource InternalSingleOrDefault <TSource> (this IObservable <TSource> source, Func <TSource, bool> predicate, bool throwError)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (predicate == null)
            {
                throw new ArgumentNullException("predicate");
            }

            var         wait = new HybridWait();
            TSource     ret = default(TSource);
            bool        got = false, error = false;
            IDisposable dis = null;

            dis = source.Subscribe(
                // the first "if (!got) check is required because the source may send next values before unsubscribing this action by dis.Dispose().
                s => { if (predicate(s))
                       {
                           if (got)
                           {
                               error = true;
                           }
                           got = true;
                           ret = s;
                       }
                },
                () => wait.Set()
                );
            wait.WaitOne();
            dis.Dispose();
            if (error)
            {
                throw new InvalidOperationException("Observed that there was more than one item in the target object");
            }
            if (!got && throwError)
            {
                throw new InvalidOperationException();
            }
            return(ret);
        }