private static TSource SingleOrDefaultInternal <TSource>(IObservable <TSource> source, bool throwOnEmpty) { var value = default(TSource); var seenValue = false; var moreThanOneElement = false; var ex = default(Exception); using (var evt = new WaitAndSetOnce()) { // // [OK] Use of unsafe Subscribe: fine to throw to our caller, behavior indistinguishable from going through the sink. // using (source.Subscribe/*Unsafe*/ (new AnonymousObserver <TSource>( v => { if (seenValue) { moreThanOneElement = true; evt.Set(); } value = v; seenValue = true; }, e => { ex = e; evt.Set(); }, () => { evt.Set(); }))) { evt.WaitOne(); } } ex.ThrowIfNotNull(); if (moreThanOneElement) { throw new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_ELEMENT); } if (throwOnEmpty && !seenValue) { throw new InvalidOperationException(Strings_Linq.NO_ELEMENTS); } return(value); }
public virtual void ForEach <TSource>(IObservable <TSource> source, Action <TSource, int> onNext) { using (var evt = new WaitAndSetOnce()) { var sink = new ForEach <TSource> .ObserverIndexed(onNext, () => evt.Set()); using (source.SubscribeSafe(sink)) { evt.WaitOne(); } sink.Error.ThrowIfNotNull(); } }
public virtual void ForEach <TSource>(IObservable <TSource> source, Action <TSource> onNext) { #if !NO_PERF using (var evt = new WaitAndSetOnce()) { var sink = new ForEach <TSource> ._(onNext, () => evt.Set()); using (source.SubscribeSafe(sink)) { evt.WaitOne(); } sink.Error.ThrowIfNotNull(); } #else ForEach_(source, onNext); #endif }