Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/rx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Rx.NET/System.Reactive.Linq/Reactive/Linq')
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/GroupedObservable.cs52
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/IQueryLanguage.cs797
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/LocalQueryMethodImplementationTypeAttribute.cs36
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Aggregates.cs2554
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Async.cs2802
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Awaiter.cs79
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Binding.cs610
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs503
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Concurrency.cs155
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Conversions.cs164
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Creation.cs624
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Events.cs1403
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Imperative.cs299
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Joins.cs91
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Multiple.cs2386
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Single.cs657
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.StandardSequenceOperators.cs923
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Time.cs1985
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable_.cs12
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/AddRef.cs55
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Aggregate.cs158
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/All.cs73
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Amb.cs173
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Any.cs115
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/AsObservable.cs60
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Average.cs703
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Buffer.cs709
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Case.cs85
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Cast.cs62
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Catch.cs183
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Collect.cs139
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/CombineLatest.cs1863
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Concat.cs52
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Contains.cs76
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Count.cs124
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DefaultIfEmpty.cs60
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Defer.cs76
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Delay.cs768
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DelaySubscription.cs76
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Dematerialize.cs63
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Distinct.cs75
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DistinctUntilChanged.cs94
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Do.cs92
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DoWhile.cs54
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ElementAt.cs75
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Empty.cs48
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Finally.cs73
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FirstAsync.cs132
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/For.cs53
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ForEach.cs122
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FromEvent.cs368
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FromEventPattern.cs143
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Generate.cs292
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GetEnumerator.cs102
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupBy.cs129
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupByUntil.cs289
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupJoin.cs302
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/If.cs81
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/IgnoreElements.cs54
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/IsEmpty.cs53
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Join.cs336
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/LastAsync.cs140
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Latest.cs145
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/LongCount.cs124
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Materialize.cs57
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Max.cs792
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MaxBy.cs108
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Merge.cs288
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Min.cs792
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MinBy.cs108
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MostRecent.cs85
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Multicast.cs82
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Never.cs20
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Next.cs156
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ObserveOn.cs87
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/OfType.cs53
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/OnErrorResumeNext.cs60
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/PushToPullAdapter.cs93
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Range.cs83
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/RefCount.cs88
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Repeat.cs127
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Return.cs51
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Sample.cs243
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Scan.cs146
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Select.cs138
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SelectMany.cs593
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SequenceEqual.cs322
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SingleAsync.cs154
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Skip.cs151
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipLast.cs125
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipUntil.cs210
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipWhile.cs139
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Sum.cs517
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Switch.cs152
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Synchronize.cs69
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Take.cs176
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeLast.cs230
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeLastBuffer.cs141
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeUntil.cs258
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeWhile.cs149
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Throttle.cs280
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Throw.cs50
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TimeInterval.cs73
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timeout.cs432
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timer.cs264
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timestamp.cs56
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToArray.cs55
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToDictionary.cs71
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToList.cs55
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToLookup.cs72
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToObservable.cs174
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Using.cs76
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Where.cs135
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/While.cs53
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Window.cs758
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Zip.cs2326
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/_.cs9
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Aggregates.cs1662
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Async.cs1796
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Awaiter.cs64
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Binding.cs158
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Blocking.cs464
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Concurrency.cs61
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Conversions.cs159
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Creation.cs462
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Events.cs653
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Imperative.cs232
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Joins.cs84
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Multiple.cs1723
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Single.cs661
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.StandardSequenceOperators.cs1265
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Time.cs1907
-rw-r--r--Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage_.cs8
133 files changed, 48522 insertions, 0 deletions
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/GroupedObservable.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/GroupedObservable.cs
new file mode 100644
index 0000000..f3ab0ad
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/GroupedObservable.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq
+{
+ class GroupedObservable<TKey, TElement> : ObservableBase<TElement>, IGroupedObservable<TKey, TElement>
+ {
+ private readonly TKey _key;
+ private readonly IObservable<TElement> _subject;
+ private readonly RefCountDisposable _refCount;
+
+ public GroupedObservable(TKey key, ISubject<TElement> subject, RefCountDisposable refCount)
+ {
+ _key = key;
+ _subject = subject;
+ _refCount = refCount;
+ }
+
+ public GroupedObservable(TKey key, ISubject<TElement> subject)
+ {
+ _key = key;
+ _subject = subject;
+ }
+
+ public TKey Key
+ {
+ get { return _key; }
+ }
+
+ protected override IDisposable SubscribeCore(IObserver<TElement> observer)
+ {
+ if (_refCount != null)
+ {
+ //
+ // [OK] Use of unsafe Subscribe: called on a known subject implementation.
+ //
+ var release = _refCount.GetDisposable();
+ var subscription = _subject.Subscribe/*Unsafe*/(observer);
+ return new CompositeDisposable(release, subscription);
+ }
+ else
+ {
+ //
+ // [OK] Use of unsafe Subscribe: called on a known subject implementation.
+ //
+ return _subject.Subscribe/*Unsafe*/(observer);
+ }
+ }
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/IQueryLanguage.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/IQueryLanguage.cs
new file mode 100644
index 0000000..27a0fe7
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/IQueryLanguage.cs
@@ -0,0 +1,797 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Concurrency;
+using System.Reactive.Joins;
+using System.Reactive.Subjects;
+using System.Threading;
+
+#if !NO_REMOTING
+using System.Runtime.Remoting.Lifetime;
+#endif
+
+#if !NO_TPL
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+ /// <summary>
+ /// Internal interface describing the LINQ to Events query language.
+ /// </summary>
+ internal interface IQueryLanguage
+ {
+ #region * Aggregates *
+
+ IObservable<TAccumulate> Aggregate<TSource, TAccumulate>(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator);
+ IObservable<TResult> Aggregate<TSource, TAccumulate, TResult>(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector);
+ IObservable<TSource> Aggregate<TSource>(IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator);
+ IObservable<bool> All<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<bool> Any<TSource>(IObservable<TSource> source);
+ IObservable<bool> Any<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<double> Average(IObservable<double> source);
+ IObservable<float> Average(IObservable<float> source);
+ IObservable<decimal> Average(IObservable<decimal> source);
+ IObservable<double> Average(IObservable<int> source);
+ IObservable<double> Average(IObservable<long> source);
+ IObservable<double?> Average(IObservable<double?> source);
+ IObservable<float?> Average(IObservable<float?> source);
+ IObservable<decimal?> Average(IObservable<decimal?> source);
+ IObservable<double?> Average(IObservable<int?> source);
+ IObservable<double?> Average(IObservable<long?> source);
+ IObservable<double> Average<TSource>(IObservable<TSource> source, Func<TSource, double> selector);
+ IObservable<float> Average<TSource>(IObservable<TSource> source, Func<TSource, float> selector);
+ IObservable<decimal> Average<TSource>(IObservable<TSource> source, Func<TSource, decimal> selector);
+ IObservable<double> Average<TSource>(IObservable<TSource> source, Func<TSource, int> selector);
+ IObservable<double> Average<TSource>(IObservable<TSource> source, Func<TSource, long> selector);
+ IObservable<double?> Average<TSource>(IObservable<TSource> source, Func<TSource, double?> selector);
+ IObservable<float?> Average<TSource>(IObservable<TSource> source, Func<TSource, float?> selector);
+ IObservable<decimal?> Average<TSource>(IObservable<TSource> source, Func<TSource, decimal?> selector);
+ IObservable<double?> Average<TSource>(IObservable<TSource> source, Func<TSource, int?> selector);
+ IObservable<double?> Average<TSource>(IObservable<TSource> source, Func<TSource, long?> selector);
+ IObservable<bool> Contains<TSource>(IObservable<TSource> source, TSource value);
+ IObservable<bool> Contains<TSource>(IObservable<TSource> source, TSource value, IEqualityComparer<TSource> comparer);
+ IObservable<int> Count<TSource>(IObservable<TSource> source);
+ IObservable<int> Count<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<TSource> ElementAt<TSource>(IObservable<TSource> source, int index);
+ IObservable<TSource> ElementAtOrDefault<TSource>(IObservable<TSource> source, int index);
+ IObservable<TSource> FirstAsync<TSource>(IObservable<TSource> source);
+ IObservable<TSource> FirstAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<TSource> FirstOrDefaultAsync<TSource>(IObservable<TSource> source);
+ IObservable<TSource> FirstOrDefaultAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<bool> IsEmpty<TSource>(IObservable<TSource> source);
+ IObservable<TSource> LastAsync<TSource>(IObservable<TSource> source);
+ IObservable<TSource> LastAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<TSource> LastOrDefaultAsync<TSource>(IObservable<TSource> source);
+ IObservable<TSource> LastOrDefaultAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<long> LongCount<TSource>(IObservable<TSource> source);
+ IObservable<long> LongCount<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<TSource> Max<TSource>(IObservable<TSource> source);
+ IObservable<TSource> Max<TSource>(IObservable<TSource> source, IComparer<TSource> comparer);
+ IObservable<double> Max(IObservable<double> source);
+ IObservable<float> Max(IObservable<float> source);
+ IObservable<decimal> Max(IObservable<decimal> source);
+ IObservable<int> Max(IObservable<int> source);
+ IObservable<long> Max(IObservable<long> source);
+ IObservable<double?> Max(IObservable<double?> source);
+ IObservable<float?> Max(IObservable<float?> source);
+ IObservable<decimal?> Max(IObservable<decimal?> source);
+ IObservable<int?> Max(IObservable<int?> source);
+ IObservable<long?> Max(IObservable<long?> source);
+ IObservable<TResult> Max<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector);
+ IObservable<TResult> Max<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector, IComparer<TResult> comparer);
+ IObservable<double> Max<TSource>(IObservable<TSource> source, Func<TSource, double> selector);
+ IObservable<float> Max<TSource>(IObservable<TSource> source, Func<TSource, float> selector);
+ IObservable<decimal> Max<TSource>(IObservable<TSource> source, Func<TSource, decimal> selector);
+ IObservable<int> Max<TSource>(IObservable<TSource> source, Func<TSource, int> selector);
+ IObservable<long> Max<TSource>(IObservable<TSource> source, Func<TSource, long> selector);
+ IObservable<double?> Max<TSource>(IObservable<TSource> source, Func<TSource, double?> selector);
+ IObservable<float?> Max<TSource>(IObservable<TSource> source, Func<TSource, float?> selector);
+ IObservable<decimal?> Max<TSource>(IObservable<TSource> source, Func<TSource, decimal?> selector);
+ IObservable<int?> Max<TSource>(IObservable<TSource> source, Func<TSource, int?> selector);
+ IObservable<long?> Max<TSource>(IObservable<TSource> source, Func<TSource, long?> selector);
+ IObservable<IList<TSource>> MaxBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector);
+ IObservable<IList<TSource>> MaxBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer);
+ IObservable<TSource> Min<TSource>(IObservable<TSource> source);
+ IObservable<TSource> Min<TSource>(IObservable<TSource> source, IComparer<TSource> comparer);
+ IObservable<double> Min(IObservable<double> source);
+ IObservable<float> Min(IObservable<float> source);
+ IObservable<decimal> Min(IObservable<decimal> source);
+ IObservable<int> Min(IObservable<int> source);
+ IObservable<long> Min(IObservable<long> source);
+ IObservable<double?> Min(IObservable<double?> source);
+ IObservable<float?> Min(IObservable<float?> source);
+ IObservable<decimal?> Min(IObservable<decimal?> source);
+ IObservable<int?> Min(IObservable<int?> source);
+ IObservable<long?> Min(IObservable<long?> source);
+ IObservable<TResult> Min<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector);
+ IObservable<TResult> Min<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector, IComparer<TResult> comparer);
+ IObservable<double> Min<TSource>(IObservable<TSource> source, Func<TSource, double> selector);
+ IObservable<float> Min<TSource>(IObservable<TSource> source, Func<TSource, float> selector);
+ IObservable<decimal> Min<TSource>(IObservable<TSource> source, Func<TSource, decimal> selector);
+ IObservable<int> Min<TSource>(IObservable<TSource> source, Func<TSource, int> selector);
+ IObservable<long> Min<TSource>(IObservable<TSource> source, Func<TSource, long> selector);
+ IObservable<double?> Min<TSource>(IObservable<TSource> source, Func<TSource, double?> selector);
+ IObservable<float?> Min<TSource>(IObservable<TSource> source, Func<TSource, float?> selector);
+ IObservable<decimal?> Min<TSource>(IObservable<TSource> source, Func<TSource, decimal?> selector);
+ IObservable<int?> Min<TSource>(IObservable<TSource> source, Func<TSource, int?> selector);
+ IObservable<long?> Min<TSource>(IObservable<TSource> source, Func<TSource, long?> selector);
+ IObservable<IList<TSource>> MinBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector);
+ IObservable<IList<TSource>> MinBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer);
+ IObservable<bool> SequenceEqual<TSource>(IObservable<TSource> first, IObservable<TSource> second);
+ IObservable<bool> SequenceEqual<TSource>(IObservable<TSource> first, IObservable<TSource> second, IEqualityComparer<TSource> comparer);
+ IObservable<bool> SequenceEqual<TSource>(IObservable<TSource> first, IEnumerable<TSource> second);
+ IObservable<bool> SequenceEqual<TSource>(IObservable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer);
+ IObservable<TSource> SingleAsync<TSource>(IObservable<TSource> source);
+ IObservable<TSource> SingleAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<TSource> SingleOrDefaultAsync<TSource>(IObservable<TSource> source);
+ IObservable<TSource> SingleOrDefaultAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<double> Sum(IObservable<double> source);
+ IObservable<float> Sum(IObservable<float> source);
+ IObservable<decimal> Sum(IObservable<decimal> source);
+ IObservable<int> Sum(IObservable<int> source);
+ IObservable<long> Sum(IObservable<long> source);
+ IObservable<double?> Sum(IObservable<double?> source);
+ IObservable<float?> Sum(IObservable<float?> source);
+ IObservable<decimal?> Sum(IObservable<decimal?> source);
+ IObservable<int?> Sum(IObservable<int?> source);
+ IObservable<long?> Sum(IObservable<long?> source);
+ IObservable<double> Sum<TSource>(IObservable<TSource> source, Func<TSource, double> selector);
+ IObservable<float> Sum<TSource>(IObservable<TSource> source, Func<TSource, float> selector);
+ IObservable<decimal> Sum<TSource>(IObservable<TSource> source, Func<TSource, decimal> selector);
+ IObservable<int> Sum<TSource>(IObservable<TSource> source, Func<TSource, int> selector);
+ IObservable<long> Sum<TSource>(IObservable<TSource> source, Func<TSource, long> selector);
+ IObservable<double?> Sum<TSource>(IObservable<TSource> source, Func<TSource, double?> selector);
+ IObservable<float?> Sum<TSource>(IObservable<TSource> source, Func<TSource, float?> selector);
+ IObservable<decimal?> Sum<TSource>(IObservable<TSource> source, Func<TSource, decimal?> selector);
+ IObservable<int?> Sum<TSource>(IObservable<TSource> source, Func<TSource, int?> selector);
+ IObservable<long?> Sum<TSource>(IObservable<TSource> source, Func<TSource, long?> selector);
+ IObservable<TSource[]> ToArray<TSource>(IObservable<TSource> source);
+ IObservable<IDictionary<TKey, TElement>> ToDictionary<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer);
+ IObservable<IDictionary<TKey, TElement>> ToDictionary<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector);
+ IObservable<IDictionary<TKey, TSource>> ToDictionary<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer);
+ IObservable<IDictionary<TKey, TSource>> ToDictionary<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector);
+ IObservable<IList<TSource>> ToList<TSource>(IObservable<TSource> source);
+ IObservable<ILookup<TKey, TElement>> ToLookup<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer);
+ IObservable<ILookup<TKey, TSource>> ToLookup<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer);
+ IObservable<ILookup<TKey, TElement>> ToLookup<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector);
+ IObservable<ILookup<TKey, TSource>> ToLookup<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector);
+
+ #endregion
+
+ #region * Async *
+
+ Func<IObservable<TResult>> FromAsyncPattern<TResult>(Func<AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, IObservable<TResult>> FromAsyncPattern<T1, TResult>(Func<T1, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, IObservable<TResult>> FromAsyncPattern<T1, T2, TResult>(Func<T1, T2, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+
+#if !NO_LARGEARITY
+ Func<T1, T2, T3, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, TResult>(Func<T1, T2, T3, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, T5, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, TResult>(Func<T1, T2, T3, T4, T5, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, T5, T6, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, TResult>(Func<T1, T2, T3, T4, T5, T6, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end);
+#endif
+
+ Func<IObservable<Unit>> FromAsyncPattern(Func<AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, IObservable<Unit>> FromAsyncPattern<T1>(Func<T1, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, IObservable<Unit>> FromAsyncPattern<T1, T2>(Func<T1, T2, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+
+#if !NO_LARGEARITY
+ Func<T1, T2, T3, IObservable<Unit>> FromAsyncPattern<T1, T2, T3>(Func<T1, T2, T3, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4>(Func<T1, T2, T3, T4, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, T5, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5>(Func<T1, T2, T3, T4, T5, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, T5, T6, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6>(Func<T1, T2, T3, T4, T5, T6, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7>(Func<T1, T2, T3, T4, T5, T6, T7, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8>(Func<T1, T2, T3, T4, T5, T6, T7, T8, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end);
+#endif
+
+ IObservable<TSource> Start<TSource>(Func<TSource> function);
+ IObservable<TSource> Start<TSource>(Func<TSource> function, IScheduler scheduler);
+
+#if !NO_TPL
+ IObservable<TSource> StartAsync<TSource>(Func<Task<TSource>> functionAsync);
+ IObservable<TSource> StartAsync<TSource>(Func<CancellationToken, Task<TSource>> functionAsync);
+#endif
+
+ IObservable<Unit> Start(Action action);
+ IObservable<Unit> Start(Action action, IScheduler scheduler);
+
+#if !NO_TPL
+ IObservable<Unit> StartAsync(Func<Task> actionAsync);
+ IObservable<Unit> StartAsync(Func<CancellationToken, Task> actionAsync);
+#endif
+
+#if !NO_TPL
+ IObservable<TResult> FromAsync<TResult>(Func<Task<TResult>> functionAsync);
+ IObservable<TResult> FromAsync<TResult>(Func<CancellationToken, Task<TResult>> functionAsync);
+ IObservable<Unit> FromAsync(Func<Task> actionAsync);
+ IObservable<Unit> FromAsync(Func<CancellationToken, Task> actionAsync);
+#endif
+
+ Func<IObservable<TResult>> ToAsync<TResult>(Func<TResult> function);
+ Func<IObservable<TResult>> ToAsync<TResult>(Func<TResult> function, IScheduler scheduler);
+ Func<T, IObservable<TResult>> ToAsync<T, TResult>(Func<T, TResult> function);
+ Func<T, IObservable<TResult>> ToAsync<T, TResult>(Func<T, TResult> function, IScheduler scheduler);
+ Func<T1, T2, IObservable<TResult>> ToAsync<T1, T2, TResult>(Func<T1, T2, TResult> function);
+ Func<T1, T2, IObservable<TResult>> ToAsync<T1, T2, TResult>(Func<T1, T2, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, IObservable<TResult>> ToAsync<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> function);
+ Func<T1, T2, T3, IObservable<TResult>> ToAsync<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, IObservable<TResult>> ToAsync<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> function);
+ Func<T1, T2, T3, T4, IObservable<TResult>> ToAsync<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> function, IScheduler scheduler);
+
+#if !NO_LARGEARITY
+ Func<T1, T2, T3, T4, T5, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, TResult>(Func<T1, T2, T3, T4, T5, TResult> function);
+ Func<T1, T2, T3, T4, T5, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, TResult>(Func<T1, T2, T3, T4, T5, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, TResult>(Func<T1, T2, T3, T4, T5, T6, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, TResult>(Func<T1, T2, T3, T4, T5, T6, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, T7, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> function, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> function);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> function, IScheduler scheduler);
+#endif
+
+ Func<IObservable<Unit>> ToAsync(Action action);
+ Func<IObservable<Unit>> ToAsync(Action action, IScheduler scheduler);
+ Func<TSource, IObservable<Unit>> ToAsync<TSource>(Action<TSource> action);
+ Func<TSource, IObservable<Unit>> ToAsync<TSource>(Action<TSource> action, IScheduler scheduler);
+ Func<T1, T2, IObservable<Unit>> ToAsync<T1, T2>(Action<T1, T2> action);
+ Func<T1, T2, IObservable<Unit>> ToAsync<T1, T2>(Action<T1, T2> action, IScheduler scheduler);
+ Func<T1, T2, T3, IObservable<Unit>> ToAsync<T1, T2, T3>(Action<T1, T2, T3> action);
+ Func<T1, T2, T3, IObservable<Unit>> ToAsync<T1, T2, T3>(Action<T1, T2, T3> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, IObservable<Unit>> ToAsync<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action);
+ Func<T1, T2, T3, T4, IObservable<Unit>> ToAsync<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, IScheduler scheduler);
+
+#if !NO_LARGEARITY
+ Func<T1, T2, T3, T4, T5, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action);
+ Func<T1, T2, T3, T4, T5, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action);
+ Func<T1, T2, T3, T4, T5, T6, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action);
+ Func<T1, T2, T3, T4, T5, T6, T7, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> action);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> action);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> action);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> action);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> action);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> action, IScheduler scheduler);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> action);
+ Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> action, IScheduler scheduler);
+#endif
+
+ #endregion
+
+ #region * Awaiter *
+
+#if HAS_AWAIT
+ AsyncSubject<TSource> GetAwaiter<TSource>(IObservable<TSource> source);
+ AsyncSubject<TSource> GetAwaiter<TSource>(IConnectableObservable<TSource> source);
+ AsyncSubject<TSource> RunAsync<TSource>(IObservable<TSource> source, CancellationToken cancellationToken);
+ AsyncSubject<TSource> RunAsync<TSource>(IConnectableObservable<TSource> source, CancellationToken cancellationToken);
+#endif
+
+ #endregion
+
+ #region * Binding *
+
+ IConnectableObservable<TResult> Multicast<TSource, TResult>(IObservable<TSource> source, ISubject<TSource, TResult> subject);
+ IObservable<TResult> Multicast<TSource, TIntermediate, TResult>(IObservable<TSource> source, Func<ISubject<TSource, TIntermediate>> subjectSelector, Func<IObservable<TIntermediate>, IObservable<TResult>> selector);
+ IConnectableObservable<TSource> Publish<TSource>(IObservable<TSource> source);
+ IObservable<TResult> Publish<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector);
+ IConnectableObservable<TSource> Publish<TSource>(IObservable<TSource> source, TSource initialValue);
+ IObservable<TResult> Publish<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TSource initialValue);
+ IConnectableObservable<TSource> PublishLast<TSource>(IObservable<TSource> source);
+ IObservable<TResult> PublishLast<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector);
+ IObservable<TSource> RefCount<TSource>(IConnectableObservable<TSource> source);
+ IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source);
+ IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, IScheduler scheduler);
+ IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector);
+ IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, IScheduler scheduler);
+ IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, TimeSpan window);
+ IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TimeSpan window);
+ IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, TimeSpan window, IScheduler scheduler);
+ IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TimeSpan window, IScheduler scheduler);
+ IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, int bufferSize, IScheduler scheduler);
+ IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, IScheduler scheduler);
+ IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, int bufferSize);
+ IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize);
+ IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, int bufferSize, TimeSpan window);
+ IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, TimeSpan window);
+ IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, int bufferSize, TimeSpan window, IScheduler scheduler);
+ IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, TimeSpan window, IScheduler scheduler);
+
+ #endregion
+
+ #region * Blocking *
+
+ IEnumerable<IList<TSource>> Chunkify<TSource>(IObservable<TSource> source);
+ IEnumerable<TResult> Collect<TSource, TResult>(IObservable<TSource> source, Func<TResult> newCollector, Func<TResult, TSource, TResult> merge);
+ IEnumerable<TResult> Collect<TSource, TResult>(IObservable<TSource> source, Func<TResult> getInitialCollector, Func<TResult, TSource, TResult> merge, Func<TResult, TResult> getNewCollector);
+ TSource First<TSource>(IObservable<TSource> source);
+ TSource First<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ TSource FirstOrDefault<TSource>(IObservable<TSource> source);
+ TSource FirstOrDefault<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ void ForEach<TSource>(IObservable<TSource> source, Action<TSource> onNext);
+ void ForEach<TSource>(IObservable<TSource> source, Action<TSource, int> onNext);
+ IEnumerator<TSource> GetEnumerator<TSource>(IObservable<TSource> source);
+ TSource Last<TSource>(IObservable<TSource> source);
+ TSource Last<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ TSource LastOrDefault<TSource>(IObservable<TSource> source);
+ TSource LastOrDefault<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IEnumerable<TSource> Latest<TSource>(IObservable<TSource> source);
+ IEnumerable<TSource> MostRecent<TSource>(IObservable<TSource> source, TSource initialValue);
+ IEnumerable<TSource> Next<TSource>(IObservable<TSource> source);
+ TSource Single<TSource>(IObservable<TSource> source);
+ TSource SingleOrDefault<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ TSource SingleOrDefault<TSource>(IObservable<TSource> source);
+ TSource Single<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ TSource Wait<TSource>(IObservable<TSource> source);
+
+ #endregion
+
+ #region * Concurrency *
+
+ IObservable<TSource> ObserveOn<TSource>(IObservable<TSource> source, IScheduler scheduler);
+#if !NO_SYNCCTX
+ IObservable<TSource> ObserveOn<TSource>(IObservable<TSource> source, SynchronizationContext context);
+#endif
+ IObservable<TSource> SubscribeOn<TSource>(IObservable<TSource> source, IScheduler scheduler);
+#if !NO_SYNCCTX
+ IObservable<TSource> SubscribeOn<TSource>(IObservable<TSource> source, SynchronizationContext context);
+#endif
+ IObservable<TSource> Synchronize<TSource>(IObservable<TSource> source);
+ IObservable<TSource> Synchronize<TSource>(IObservable<TSource> source, object gate);
+
+ #endregion
+
+ #region * Conversions *
+
+ IDisposable Subscribe<TSource>(IEnumerable<TSource> source, IObserver<TSource> observer);
+ IDisposable Subscribe<TSource>(IEnumerable<TSource> source, IObserver<TSource> observer, IScheduler scheduler);
+ IEnumerable<TSource> ToEnumerable<TSource>(IObservable<TSource> source);
+ IEventSource<Unit> ToEvent(IObservable<Unit> source);
+ IEventSource<TSource> ToEvent<TSource>(IObservable<TSource> source);
+#if !NO_EVENTARGS_CONSTRAINT
+ IEventPatternSource<TEventArgs> ToEventPattern<TEventArgs>(IObservable<EventPattern<TEventArgs>> source) where TEventArgs : EventArgs;
+#else
+ IEventPatternSource<TEventArgs> ToEventPattern<TEventArgs>(IObservable<EventPattern<TEventArgs>> source);
+#endif
+ IObservable<TSource> ToObservable<TSource>(IEnumerable<TSource> source);
+ IObservable<TSource> ToObservable<TSource>(IEnumerable<TSource> source, IScheduler scheduler);
+
+ #endregion
+
+ #region * Creation *
+
+ IObservable<TSource> Create<TSource>(Func<IObserver<TSource>, IDisposable> subscribe);
+ IObservable<TSource> Create<TSource>(Func<IObserver<TSource>, Action> subscribe);
+
+#if !NO_TPL
+ IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task> subscribeAsync);
+ IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task> subscribeAsync);
+ IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task<IDisposable>> subscribeAsync);
+ IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task<IDisposable>> subscribeAsync);
+ IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task<Action>> subscribeAsync);
+ IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task<Action>> subscribeAsync);
+#endif
+
+ IObservable<TValue> Defer<TValue>(Func<IObservable<TValue>> observableFactory);
+
+#if !NO_TPL
+ IObservable<TValue> Defer<TValue>(Func<Task<IObservable<TValue>>> observableFactoryAsync);
+ IObservable<TValue> Defer<TValue>(Func<CancellationToken, Task<IObservable<TValue>>> observableFactoryAsync);
+#endif
+
+ IObservable<TResult> Empty<TResult>();
+ IObservable<TResult> Empty<TResult>(IScheduler scheduler);
+ IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector);
+ IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, IScheduler scheduler);
+ IObservable<TResult> Never<TResult>();
+ IObservable<int> Range(int start, int count);
+ IObservable<int> Range(int start, int count, IScheduler scheduler);
+ IObservable<TResult> Repeat<TResult>(TResult value);
+ IObservable<TResult> Repeat<TResult>(TResult value, IScheduler scheduler);
+ IObservable<TResult> Repeat<TResult>(TResult value, int repeatCount);
+ IObservable<TResult> Repeat<TResult>(TResult value, int repeatCount, IScheduler scheduler);
+ IObservable<TResult> Return<TResult>(TResult value);
+ IObservable<TResult> Return<TResult>(TResult value, IScheduler scheduler);
+ IObservable<TResult> Throw<TResult>(Exception exception);
+ IObservable<TResult> Throw<TResult>(Exception exception, IScheduler scheduler);
+ IObservable<TSource> Using<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IObservable<TSource>> observableFactory) where TResource : IDisposable;
+
+#if !NO_TPL
+ IObservable<TSource> Using<TSource, TResource>(Func<CancellationToken, Task<TResource>> resourceFactoryAsync, Func<TResource, CancellationToken, Task<IObservable<TSource>>> observableFactoryAsync) where TResource : IDisposable;
+#endif
+
+ #endregion
+
+ #region * Events *
+
+#if !NO_EVENTARGS_CONSTRAINT
+ IObservable<EventPattern<EventArgs>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler);
+ IObservable<EventPattern<EventArgs>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IScheduler scheduler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<EventArgs>> FromEventPattern(object target, string eventName);
+ IObservable<EventPattern<EventArgs>> FromEventPattern(object target, string eventName, IScheduler scheduler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName, IScheduler scheduler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName, IScheduler scheduler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<EventArgs>> FromEventPattern(Type type, string eventName);
+ IObservable<EventPattern<EventArgs>> FromEventPattern(Type type, string eventName, IScheduler scheduler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName, IScheduler scheduler) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName) where TEventArgs : EventArgs;
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName, IScheduler scheduler) where TEventArgs : EventArgs;
+#else
+ IObservable<EventPattern<object>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler);
+ IObservable<EventPattern<object>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IScheduler scheduler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler, IScheduler scheduler);
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler);
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler);
+ IObservable<EventPattern<object>> FromEventPattern(object target, string eventName);
+ IObservable<EventPattern<object>> FromEventPattern(object target, string eventName, IScheduler scheduler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName, IScheduler scheduler);
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName);
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName, IScheduler scheduler);
+ IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName);
+ IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName, IScheduler scheduler);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName);
+ IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName, IScheduler scheduler);
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName);
+ IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName, IScheduler scheduler);
+#endif
+ IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Func<Action<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler);
+ IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Func<Action<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler);
+ IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler);
+ IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler);
+ IObservable<TEventArgs> FromEvent<TEventArgs>(Action<Action<TEventArgs>> addHandler, Action<Action<TEventArgs>> removeHandler);
+ IObservable<TEventArgs> FromEvent<TEventArgs>(Action<Action<TEventArgs>> addHandler, Action<Action<TEventArgs>> removeHandler, IScheduler scheduler);
+ IObservable<Unit> FromEvent(Action<Action> addHandler, Action<Action> removeHandler);
+ IObservable<Unit> FromEvent(Action<Action> addHandler, Action<Action> removeHandler, IScheduler scheduler);
+
+ #endregion
+
+ #region * Imperative *
+
+#if !NO_TPL
+ Task ForEachAsync<TSource>(IObservable<TSource> source, Action<TSource> onNext);
+ Task ForEachAsync<TSource>(IObservable<TSource> source, Action<TSource> onNext, CancellationToken cancellationToken);
+ Task ForEachAsync<TSource>(IObservable<TSource> source, Action<TSource, int> onNext);
+ Task ForEachAsync<TSource>(IObservable<TSource> source, Action<TSource, int> onNext, CancellationToken cancellationToken);
+#endif
+
+ IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources, IObservable<TResult> defaultSource);
+ IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources, IScheduler scheduler);
+ IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources);
+ IObservable<TSource> DoWhile<TSource>(IObservable<TSource> source, Func<bool> condition);
+ IObservable<TResult> For<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IObservable<TResult>> resultSelector);
+ IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource, IObservable<TResult> elseSource);
+ IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource);
+ IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource, IScheduler scheduler);
+ IObservable<TSource> While<TSource>(Func<bool> condition, IObservable<TSource> source);
+
+ #endregion
+
+ #region * Joins *
+
+ Pattern<TLeft, TRight> And<TLeft, TRight>(IObservable<TLeft> left, IObservable<TRight> right);
+ Plan<TResult> Then<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector);
+ IObservable<TResult> When<TResult>(params Plan<TResult>[] plans);
+ IObservable<TResult> When<TResult>(IEnumerable<Plan<TResult>> plans);
+
+ #endregion
+
+ #region * Multiple *
+
+ IObservable<TSource> Amb<TSource>(IObservable<TSource> first, IObservable<TSource> second);
+ IObservable<TSource> Amb<TSource>(params IObservable<TSource>[] sources);
+ IObservable<TSource> Amb<TSource>(IEnumerable<IObservable<TSource>> sources);
+ IObservable<IList<TSource>> Buffer<TSource, TBufferClosing>(IObservable<TSource> source, Func<IObservable<TBufferClosing>> bufferClosingSelector);
+ IObservable<IList<TSource>> Buffer<TSource, TBufferOpening, TBufferClosing>(IObservable<TSource> source, IObservable<TBufferOpening> bufferOpenings, Func<TBufferOpening, IObservable<TBufferClosing>> bufferClosingSelector);
+ IObservable<IList<TSource>> Buffer<TSource, TBufferBoundary>(IObservable<TSource> source, IObservable<TBufferBoundary> bufferBoundaries);
+ IObservable<TSource> Catch<TSource, TException>(IObservable<TSource> source, Func<TException, IObservable<TSource>> handler) where TException : Exception;
+ IObservable<TSource> Catch<TSource>(IObservable<TSource> first, IObservable<TSource> second);
+ IObservable<TSource> Catch<TSource>(params IObservable<TSource>[] sources);
+ IObservable<TSource> Catch<TSource>(IEnumerable<IObservable<TSource>> sources);
+ IObservable<TResult> CombineLatest<TFirst, TSecond, TResult>(IObservable<TFirst> first, IObservable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector);
+
+#if !NO_PERF
+
+ IObservable<TResult> CombineLatest<T1, T2, T3, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, Func<T1, T2, T3, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, Func<T1, T2, T3, T4, TResult> resultSelector);
+
+#if !NO_LARGEARITY
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, Func<T1, T2, T3, T4, T5, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, Func<T1, T2, T3, T4, T5, T6, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, Func<T1, T2, T3, T4, T5, T6, T7, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, IObservable<T15> source15, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> resultSelector);
+ IObservable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, IObservable<T15> source15, IObservable<T16> source16, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> resultSelector);
+#endif
+
+#endif
+
+ IObservable<TResult> CombineLatest<TSource, TResult>(IEnumerable<IObservable<TSource>> sources, Func<IList<TSource>, TResult> resultSelector);
+ IObservable<IList<TSource>> CombineLatest<TSource>(IEnumerable<IObservable<TSource>> sources);
+ IObservable<IList<TSource>> CombineLatest<TSource>(params IObservable<TSource>[] sources);
+ IObservable<TSource> Concat<TSource>(IObservable<TSource> first, IObservable<TSource> second);
+ IObservable<TSource> Concat<TSource>(params IObservable<TSource>[] sources);
+ IObservable<TSource> Concat<TSource>(IEnumerable<IObservable<TSource>> sources);
+ IObservable<TSource> Concat<TSource>(IObservable<IObservable<TSource>> sources);
+ IObservable<TSource> Merge<TSource>(IObservable<IObservable<TSource>> sources);
+ IObservable<TSource> Merge<TSource>(IObservable<IObservable<TSource>> sources, int maxConcurrent);
+ IObservable<TSource> Merge<TSource>(IEnumerable<IObservable<TSource>> sources, int maxConcurrent);
+ IObservable<TSource> Merge<TSource>(IEnumerable<IObservable<TSource>> sources, int maxConcurrent, IScheduler scheduler);
+ IObservable<TSource> Merge<TSource>(IObservable<TSource> first, IObservable<TSource> second);
+ IObservable<TSource> Merge<TSource>(IObservable<TSource> first, IObservable<TSource> second, IScheduler scheduler);
+ IObservable<TSource> Merge<TSource>(params IObservable<TSource>[] sources);
+ IObservable<TSource> Merge<TSource>(IScheduler scheduler, params IObservable<TSource>[] sources);
+ IObservable<TSource> Merge<TSource>(IEnumerable<IObservable<TSource>> sources);
+ IObservable<TSource> Merge<TSource>(IEnumerable<IObservable<TSource>> sources, IScheduler scheduler);
+ IObservable<TSource> OnErrorResumeNext<TSource>(IObservable<TSource> first, IObservable<TSource> second);
+ IObservable<TSource> OnErrorResumeNext<TSource>(params IObservable<TSource>[] sources);
+ IObservable<TSource> OnErrorResumeNext<TSource>(IEnumerable<IObservable<TSource>> sources);
+ IObservable<TSource> SkipUntil<TSource, TOther>(IObservable<TSource> source, IObservable<TOther> other);
+ IObservable<TSource> Switch<TSource>(IObservable<IObservable<TSource>> sources);
+ IObservable<TSource> TakeUntil<TSource, TOther>(IObservable<TSource> source, IObservable<TOther> other);
+ IObservable<IObservable<TSource>> Window<TSource, TWindowClosing>(IObservable<TSource> source, Func<IObservable<TWindowClosing>> windowClosingSelector);
+ IObservable<IObservable<TSource>> Window<TSource, TWindowOpening, TWindowClosing>(IObservable<TSource> source, IObservable<TWindowOpening> windowOpenings, Func<TWindowOpening, IObservable<TWindowClosing>> windowClosingSelector);
+ IObservable<IObservable<TSource>> Window<TSource, TWindowBoundary>(IObservable<TSource> source, IObservable<TWindowBoundary> windowBoundaries);
+ IObservable<TResult> Zip<TFirst, TSecond, TResult>(IObservable<TFirst> first, IObservable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector);
+ IObservable<TResult> Zip<TSource, TResult>(IEnumerable<IObservable<TSource>> sources, Func<IList<TSource>, TResult> resultSelector);
+ IObservable<IList<TSource>> Zip<TSource>(IEnumerable<IObservable<TSource>> sources);
+ IObservable<IList<TSource>> Zip<TSource>(params IObservable<TSource>[] sources);
+
+#if !NO_PERF
+
+ IObservable<TResult> Zip<T1, T2, T3, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, Func<T1, T2, T3, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, Func<T1, T2, T3, T4, TResult> resultSelector);
+
+#if !NO_LARGEARITY
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, Func<T1, T2, T3, T4, T5, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, Func<T1, T2, T3, T4, T5, T6, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, Func<T1, T2, T3, T4, T5, T6, T7, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, IObservable<T15> source15, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> resultSelector);
+ IObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, IObservable<T15> source15, IObservable<T16> source16, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> resultSelector);
+#endif
+
+#endif
+
+ IObservable<TResult> Zip<TFirst, TSecond, TResult>(IObservable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector);
+
+#if !NO_TPL
+ IObservable<TSource> Concat<TSource>(IObservable<Task<TSource>> sources);
+ IObservable<TSource> Merge<TSource>(IObservable<Task<TSource>> sources);
+ IObservable<TSource> Switch<TSource>(IObservable<Task<TSource>> sources);
+#endif
+
+ #endregion
+
+ #region * Single *
+
+ IObservable<TSource> AsObservable<TSource>(IObservable<TSource> source);
+ IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, int count);
+ IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, int count, int skip);
+ IObservable<TSource> Dematerialize<TSource>(IObservable<Notification<TSource>> source);
+ IObservable<TSource> DistinctUntilChanged<TSource>(IObservable<TSource> source);
+ IObservable<TSource> DistinctUntilChanged<TSource>(IObservable<TSource> source, IEqualityComparer<TSource> comparer);
+ IObservable<TSource> DistinctUntilChanged<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector);
+ IObservable<TSource> DistinctUntilChanged<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer);
+ IObservable<TSource> Do<TSource>(IObservable<TSource> source, Action<TSource> onNext);
+ IObservable<TSource> Do<TSource>(IObservable<TSource> source, Action<TSource> onNext, Action onCompleted);
+ IObservable<TSource> Do<TSource>(IObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError);
+ IObservable<TSource> Do<TSource>(IObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted);
+ IObservable<TSource> Do<TSource>(IObservable<TSource> source, IObserver<TSource> observer);
+ IObservable<TSource> Finally<TSource>(IObservable<TSource> source, Action finallyAction);
+ IObservable<TSource> IgnoreElements<TSource>(IObservable<TSource> source);
+ IObservable<Notification<TSource>> Materialize<TSource>(IObservable<TSource> source);
+ IObservable<TSource> Repeat<TSource>(IObservable<TSource> source);
+ IObservable<TSource> Repeat<TSource>(IObservable<TSource> source, int repeatCount);
+ IObservable<TSource> Retry<TSource>(IObservable<TSource> source);
+ IObservable<TSource> Retry<TSource>(IObservable<TSource> source, int retryCount);
+ IObservable<TAccumulate> Scan<TSource, TAccumulate>(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator);
+ IObservable<TSource> Scan<TSource>(IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator);
+ IObservable<TSource> SkipLast<TSource>(IObservable<TSource> source, int count);
+ IObservable<TSource> StartWith<TSource>(IObservable<TSource> source, params TSource[] values);
+ IObservable<TSource> StartWith<TSource>(IObservable<TSource> source, IScheduler scheduler, params TSource[] values);
+ IObservable<TSource> TakeLast<TSource>(IObservable<TSource> source, int count);
+ IObservable<TSource> TakeLast<TSource>(IObservable<TSource> source, int count, IScheduler scheduler);
+ IObservable<IList<TSource>> TakeLastBuffer<TSource>(IObservable<TSource> source, int count);
+ IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, int count, int skip);
+ IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, int count);
+
+ #endregion
+
+ #region * StandardSequenceOperators *
+
+ IObservable<TResult> Cast<TResult>(IObservable<object> source);
+ IObservable<TSource> DefaultIfEmpty<TSource>(IObservable<TSource> source);
+ IObservable<TSource> DefaultIfEmpty<TSource>(IObservable<TSource> source, TSource defaultValue);
+ IObservable<TSource> Distinct<TSource>(IObservable<TSource> source);
+ IObservable<TSource> Distinct<TSource>(IObservable<TSource> source, IEqualityComparer<TSource> comparer);
+ IObservable<TSource> Distinct<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector);
+ IObservable<TSource> Distinct<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer);
+ IObservable<IGroupedObservable<TKey, TElement>> GroupBy<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector);
+ IObservable<IGroupedObservable<TKey, TSource>> GroupBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer);
+ IObservable<IGroupedObservable<TKey, TSource>> GroupBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector);
+ IObservable<IGroupedObservable<TKey, TElement>> GroupBy<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer);
+ IObservable<IGroupedObservable<TKey, TElement>> GroupByUntil<TSource, TKey, TElement, TDuration>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedObservable<TKey, TElement>, IObservable<TDuration>> durationSelector, IEqualityComparer<TKey> comparer);
+ IObservable<IGroupedObservable<TKey, TElement>> GroupByUntil<TSource, TKey, TElement, TDuration>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedObservable<TKey, TElement>, IObservable<TDuration>> durationSelector);
+ IObservable<IGroupedObservable<TKey, TSource>> GroupByUntil<TSource, TKey, TDuration>(IObservable<TSource> source, Func<TSource, TKey> keySelector,Func<IGroupedObservable<TKey, TSource>, IObservable<TDuration>> durationSelector, IEqualityComparer<TKey> comparer);
+ IObservable<IGroupedObservable<TKey, TSource>> GroupByUntil<TSource, TKey, TDuration>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<IGroupedObservable<TKey, TSource>, IObservable<TDuration>> durationSelector);
+ IObservable<TResult> GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, IObservable<TRight>, TResult> resultSelector);
+ IObservable<TResult> Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, TRight, TResult> resultSelector);
+ IObservable<TResult> OfType<TResult>(IObservable<object> source);
+ IObservable<TResult> Select<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector);
+ IObservable<TResult> Select<TSource, TResult>(IObservable<TSource> source, Func<TSource, int, TResult> selector);
+ IObservable<TOther> SelectMany<TSource, TOther>(IObservable<TSource> source, IObservable<TOther> other);
+ IObservable<TResult> SelectMany<TSource, TResult>(IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector);
+ IObservable<TResult> SelectMany<TSource, TCollection, TResult>(IObservable<TSource> source, Func<TSource, IObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector);
+ IObservable<TResult> SelectMany<TSource, TResult>(IObservable<TSource> source, Func<TSource, IObservable<TResult>> onNext, Func<Exception, IObservable<TResult>> onError, Func<IObservable<TResult>> onCompleted);
+ IObservable<TResult> SelectMany<TSource, TResult>(IObservable<TSource> source, Func<TSource, IEnumerable<TResult>> selector);
+ IObservable<TResult> SelectMany<TSource, TCollection, TResult>(IObservable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector);
+ IObservable<TSource> Skip<TSource>(IObservable<TSource> source, int count);
+ IObservable<TSource> SkipWhile<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<TSource> SkipWhile<TSource>(IObservable<TSource> source, Func<TSource, int, bool> predicate);
+ IObservable<TSource> Take<TSource>(IObservable<TSource> source, int count);
+ IObservable<TSource> Take<TSource>(IObservable<TSource> source, int count, IScheduler scheduler);
+ IObservable<TSource> TakeWhile<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<TSource> TakeWhile<TSource>(IObservable<TSource> source, Func<TSource, int, bool> predicate);
+ IObservable<TSource> Where<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate);
+ IObservable<TSource> Where<TSource>(IObservable<TSource> source, Func<TSource, int, bool> predicate);
+
+#if !NO_TPL
+ IObservable<TResult> SelectMany<TSource, TResult>(IObservable<TSource> source, Func<TSource, Task<TResult>> selector);
+ IObservable<TResult> SelectMany<TSource, TResult>(IObservable<TSource> source, Func<TSource, CancellationToken, Task<TResult>> selector);
+ IObservable<TResult> SelectMany<TSource, TTaskResult, TResult>(IObservable<TSource> source, Func<TSource, Task<TTaskResult>> taskSelector, Func<TSource, TTaskResult, TResult> resultSelector);
+ IObservable<TResult> SelectMany<TSource, TTaskResult, TResult>(IObservable<TSource> source, Func<TSource, CancellationToken, Task<TTaskResult>> taskSelector, Func<TSource, TTaskResult, TResult> resultSelector);
+#endif
+
+ #endregion
+
+ #region * Time *
+
+ IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan);
+ IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan, IScheduler scheduler);
+ IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift);
+ IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler);
+ IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan, int count);
+ IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan, int count, IScheduler scheduler);
+ IObservable<TSource> Delay<TSource>(IObservable<TSource> source, TimeSpan dueTime);
+ IObservable<TSource> Delay<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler);
+ IObservable<TSource> Delay<TSource>(IObservable<TSource> source, DateTimeOffset dueTime);
+ IObservable<TSource> Delay<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler);
+ IObservable<TSource> Delay<TSource, TDelay>(IObservable<TSource> source, Func<TSource, IObservable<TDelay>> delayDurationSelector);
+ IObservable<TSource> Delay<TSource, TDelay>(IObservable<TSource> source, IObservable<TDelay> subscriptionDelay, Func<TSource, IObservable<TDelay>> delayDurationSelector);
+ IObservable<TSource> DelaySubscription<TSource>(IObservable<TSource> source, TimeSpan dueTime);
+ IObservable<TSource> DelaySubscription<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler);
+ IObservable<TSource> DelaySubscription<TSource>(IObservable<TSource> source, DateTimeOffset dueTime);
+ IObservable<TSource> DelaySubscription<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler);
+ IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, TimeSpan> timeSelector);
+ IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, TimeSpan> timeSelector, IScheduler scheduler);
+ IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, DateTimeOffset> timeSelector);
+ IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, DateTimeOffset> timeSelector, IScheduler scheduler);
+ IObservable<long> Interval(TimeSpan period);
+ IObservable<long> Interval(TimeSpan period, IScheduler scheduler);
+ IObservable<TSource> Sample<TSource>(IObservable<TSource> source, TimeSpan interval);
+ IObservable<TSource> Sample<TSource>(IObservable<TSource> source, TimeSpan interval, IScheduler scheduler);
+ IObservable<TSource> Sample<TSource, TSample>(IObservable<TSource> source, IObservable<TSample> sampler);
+ IObservable<TSource> Skip<TSource>(IObservable<TSource> source, TimeSpan duration);
+ IObservable<TSource> Skip<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler);
+ IObservable<TSource> SkipLast<TSource>(IObservable<TSource> source, TimeSpan duration);
+ IObservable<TSource> SkipLast<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler);
+ IObservable<TSource> SkipUntil<TSource>(IObservable<TSource> source, DateTimeOffset startTime);
+ IObservable<TSource> SkipUntil<TSource>(IObservable<TSource> source, DateTimeOffset startTime, IScheduler scheduler);
+ IObservable<TSource> Take<TSource>(IObservable<TSource> source, TimeSpan duration);
+ IObservable<TSource> Take<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler);
+ IObservable<TSource> TakeLast<TSource>(IObservable<TSource> source, TimeSpan duration);
+ IObservable<TSource> TakeLast<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler);
+ IObservable<TSource> TakeLast<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler timerScheduler, IScheduler loopScheduler);
+ IObservable<IList<TSource>> TakeLastBuffer<TSource>(IObservable<TSource> source, TimeSpan duration);
+ IObservable<IList<TSource>> TakeLastBuffer<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler);
+ IObservable<TSource> TakeUntil<TSource>(IObservable<TSource> source, DateTimeOffset endTime);
+ IObservable<TSource> TakeUntil<TSource>(IObservable<TSource> source, DateTimeOffset endTime, IScheduler scheduler);
+ IObservable<TSource> Throttle<TSource>(IObservable<TSource> source, TimeSpan dueTime);
+ IObservable<TSource> Throttle<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler);
+ IObservable<TSource> Throttle<TSource, TThrottle>(IObservable<TSource> source, Func<TSource, IObservable<TThrottle>> throttleDurationSelector);
+ IObservable<System.Reactive.TimeInterval<TSource>> TimeInterval<TSource>(IObservable<TSource> source);
+ IObservable<System.Reactive.TimeInterval<TSource>> TimeInterval<TSource>(IObservable<TSource> source, IScheduler scheduler);
+ IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, TimeSpan dueTime);
+ IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler);
+ IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, TimeSpan dueTime, IObservable<TSource> other);
+ IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, TimeSpan dueTime, IObservable<TSource> other, IScheduler scheduler);
+ IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, DateTimeOffset dueTime);
+ IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler);
+ IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IObservable<TSource> other);
+ IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IObservable<TSource> other, IScheduler scheduler);
+ IObservable<TSource> Timeout<TSource, TTimeout>(IObservable<TSource> source, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector);
+ IObservable<TSource> Timeout<TSource, TTimeout>(IObservable<TSource> source, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector, IObservable<TSource> other);
+ IObservable<TSource> Timeout<TSource, TTimeout>(IObservable<TSource> source, IObservable<TTimeout> firstTimeout, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector);
+ IObservable<TSource> Timeout<TSource, TTimeout>(IObservable<TSource> source, IObservable<TTimeout> firstTimeout, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector, IObservable<TSource> other);
+ IObservable<long> Timer(TimeSpan dueTime);
+ IObservable<long> Timer(DateTimeOffset dueTime);
+ IObservable<long> Timer(TimeSpan dueTime, TimeSpan period);
+ IObservable<long> Timer(DateTimeOffset dueTime, TimeSpan period);
+ IObservable<long> Timer(TimeSpan dueTime, IScheduler scheduler);
+ IObservable<long> Timer(DateTimeOffset dueTime, IScheduler scheduler);
+ IObservable<long> Timer(TimeSpan dueTime, TimeSpan period, IScheduler scheduler);
+ IObservable<long> Timer(DateTimeOffset dueTime, TimeSpan period, IScheduler scheduler);
+ IObservable<Timestamped<TSource>> Timestamp<TSource>(IObservable<TSource> source);
+ IObservable<Timestamped<TSource>> Timestamp<TSource>(IObservable<TSource> source, IScheduler scheduler);
+ IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan);
+ IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan, IScheduler scheduler);
+ IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift);
+ IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler);
+ IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan, int count);
+ IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan, int count, IScheduler scheduler);
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/LocalQueryMethodImplementationTypeAttribute.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/LocalQueryMethodImplementationTypeAttribute.cs
new file mode 100644
index 0000000..f8cb882
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/LocalQueryMethodImplementationTypeAttribute.cs
@@ -0,0 +1,36 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System;
+using System.ComponentModel;
+
+namespace System.Reactive.Linq
+{
+ /// <summary>
+ /// Attribute applied to static classes providing expression tree forms of query methods,
+ /// mapping those to the corresponding methods for local query execution on the specified
+ /// target class type.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
+ public sealed class LocalQueryMethodImplementationTypeAttribute : Attribute
+ {
+ private readonly Type _targetType;
+
+ /// <summary>
+ /// Creates a new mapping to the specified local execution query method implementation type.
+ /// </summary>
+ /// <param name="targetType">Type with query methods for local execution.</param>
+ public LocalQueryMethodImplementationTypeAttribute(Type targetType)
+ {
+ _targetType = targetType;
+ }
+
+ /// <summary>
+ /// Gets the type with the implementation of local query methods.
+ /// </summary>
+ public Type TargetType
+ {
+ get { return _targetType; }
+ }
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Aggregates.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Aggregates.cs
new file mode 100644
index 0000000..b541765
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Aggregates.cs
@@ -0,0 +1,2554 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region + Aggregate +
+
+ /// <summary>
+ /// Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified seed value is used as the initial accumulator value.
+ /// For aggregation behavior with incremental intermediate results, see <see cref="Observable.Scan&lt;TSource, Accumulate&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TAccumulate">The type of the result of the aggregation.</typeparam>
+ /// <param name="source">An observable sequence to aggregate over.</param>
+ /// <param name="seed">The initial accumulator value.</param>
+ /// <param name="accumulator">An accumulator function to be invoked on each element.</param>
+ /// <returns>An observable sequence containing a single element with the final accumulator value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="accumulator"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TAccumulate> Aggregate<TSource, TAccumulate>(this IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (accumulator == null)
+ throw new ArgumentNullException("accumulator");
+
+ return s_impl.Aggregate<TSource, TAccumulate>(source, seed, accumulator);
+ }
+
+ /// <summary>
+ /// Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified seed value is used as the initial accumulator value,
+ /// and the specified result selector function is used to select the result value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TAccumulate">The type of the accumulator value.</typeparam>
+ /// <typeparam name="TResult">The type of the resulting value.</typeparam>
+ /// <param name="source">An observable sequence to aggregate over.</param>
+ /// <param name="seed">The initial accumulator value.</param>
+ /// <param name="accumulator">An accumulator function to be invoked on each element.</param>
+ /// <param name="resultSelector">A function to transform the final accumulator value into the result value.</param>
+ /// <returns>An observable sequence containing a single element with the final accumulator value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="accumulator"/> or <paramref name="resultSelector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TResult> Aggregate<TSource, TAccumulate, TResult>(this IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (accumulator == null)
+ throw new ArgumentNullException("accumulator");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Aggregate<TSource, TAccumulate, TResult>(source, seed, accumulator, resultSelector);
+ }
+
+ /// <summary>
+ /// Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence.
+ /// For aggregation behavior with incremental intermediate results, see <see cref="Observable.Scan&lt;TSource&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence and the result of the aggregation.</typeparam>
+ /// <param name="source">An observable sequence to aggregate over.</param>
+ /// <param name="accumulator">An accumulator function to be invoked on each element.</param>
+ /// <returns>An observable sequence containing a single element with the final accumulator value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="accumulator"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TSource> Aggregate<TSource>(this IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (accumulator == null)
+ throw new ArgumentNullException("accumulator");
+
+ return s_impl.Aggregate<TSource>(source, accumulator);
+ }
+
+ #endregion
+
+ #region + All +
+
+ /// <summary>
+ /// Determines whether all elements of an observable sequence satisfy a condition.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence whose elements to apply the predicate to.</param>
+ /// <param name="predicate">A function to test each element for a condition.</param>
+ /// <returns>An observable sequence containing a single element determining whether all elements in the source sequence pass the test in the specified predicate.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<bool> All<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.All<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + Any +
+
+ /// <summary>
+ /// Determines whether an observable sequence contains any elements.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to check for non-emptiness.</param>
+ /// <returns>An observable sequence containing a single element determining whether the source sequence contains any elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<bool> Any<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Any<TSource>(source);
+ }
+
+ /// <summary>
+ /// Determines whether any element of an observable sequence satisfies a condition.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence whose elements to apply the predicate to.</param>
+ /// <param name="predicate">A function to test each element for a condition.</param>
+ /// <returns>An observable sequence containing a single element determining whether any elements in the source sequence pass the test in the specified predicate.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<bool> Any<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.Any<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + Average +
+
+ /// <summary>
+ /// Computes the average of an observable sequence of <see cref="T:System.Double" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Double" /> values to calculate the average of.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Average(this IObservable<double> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Average(source);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of <see cref="T:System.Single" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Single" /> values to calculate the average of.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float> Average(this IObservable<float> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Average(source);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of <see cref="T:System.Decimal" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Decimal" /> values to calculate the average of.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Decimal.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal> Average(this IObservable<decimal> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Average(source);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of <see cref="T:System.Int32" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Int32" /> values to calculate the average of.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Average(this IObservable<int> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Average(source);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of <see cref="T:System.Int64" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Int64" /> values to calculate the average of.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Average(this IObservable<long> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Average(source);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of nullable <see cref="T:System.Double" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Double" /> values to calculate the average of.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Average(this IObservable<double?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Average(source);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of nullable <see cref="T:System.Single" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Single" /> values to calculate the average of.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float?> Average(this IObservable<float?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Average(source);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of nullable <see cref="T:System.Decimal" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Decimal" /> values to calculate the average of.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Decimal.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal?> Average(this IObservable<decimal?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Average(source);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of nullable <see cref="T:System.Int32" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Int32" /> values to calculate the average of.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ public static IObservable<double?> Average(this IObservable<int?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Average(source);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of nullable <see cref="T:System.Int64" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Int64" /> values to calculate the average of.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Average(this IObservable<long?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Average(source);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of <see cref="T:System.Decimal" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to calculate the average of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Decimal.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal> Average<TSource>(this IObservable<TSource> source, Func<TSource, decimal> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Average<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of <see cref="T:System.Double" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to calculate the average of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Average<TSource>(this IObservable<TSource> source, Func<TSource, double> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Average<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of <see cref="T:System.Single" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to calculate the average of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float> Average<TSource>(this IObservable<TSource> source, Func<TSource, float> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Average<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of <see cref="T:System.Int32" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to calculate the average of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Average<TSource>(this IObservable<TSource> source, Func<TSource, int> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Average<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of <see cref="T:System.Int64" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to calculate the average of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Average<TSource>(this IObservable<TSource> source, Func<TSource, long> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Average<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of nullable <see cref="T:System.Decimal" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to calculate the average of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Decimal.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal?> Average<TSource>(this IObservable<TSource> source, Func<TSource, decimal?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Average<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of nullable <see cref="T:System.Double" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to calculate the average of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Average<TSource>(this IObservable<TSource> source, Func<TSource, double?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Average<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of nullable <see cref="T:System.Single" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to calculate the average of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float?> Average<TSource>(this IObservable<TSource> source, Func<TSource, float?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Average<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of nullable <see cref="T:System.Int32" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to calculate the average of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Average<TSource>(this IObservable<TSource> source, Func<TSource, int?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Average<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the average of an observable sequence of nullable <see cref="T:System.Int64" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to calculate the average of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Average<TSource>(this IObservable<TSource> source, Func<TSource, long?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Average<TSource>(source, selector);
+ }
+
+ #endregion
+
+ #region + Contains +
+
+ /// <summary>
+ /// Determines whether an observable sequence contains a specified element by using the default equality comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence in which to locate a value.</param>
+ /// <param name="value">The value to locate in the source sequence.</param>
+ /// <returns>An observable sequence containing a single element determining whether the source sequence contains an element that has the specified value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<bool> Contains<TSource>(this IObservable<TSource> source, TSource value)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Contains<TSource>(source, value);
+ }
+
+ /// <summary>
+ /// Determines whether an observable sequence contains a specified element by using a specified System.Collections.Generic.IEqualityComparer&lt;T&gt;.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence in which to locate a value.</param>
+ /// <param name="value">The value to locate in the source sequence.</param>
+ /// <param name="comparer">An equality comparer to compare elements.</param>
+ /// <returns>An observable sequence containing a single element determining whether the source sequence contains an element that has the specified value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<bool> Contains<TSource>(this IObservable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.Contains<TSource>(source, value, comparer);
+ }
+
+ #endregion
+
+ #region + Count +
+
+ /// <summary>
+ /// Returns an observable sequence containing an <see cref="T:System.Int32" /> that represents the total number of elements in an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence that contains elements to be counted.</param>
+ /// <returns>An observable sequence containing a single element with the number of elements in the input sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The number of elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int> Count<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Count<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence containing an <see cref="T:System.Int32" /> that represents how many elements in the specified observable sequence satisfy a condition.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence that contains elements to be counted.</param>
+ /// <param name="predicate">A function to test each element for a condition.</param>
+ /// <returns>An observable sequence containing a single element with a number that represents how many elements in the input sequence satisfy the condition in the predicate function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int> Count<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.Count<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + ElementAt +
+
+ /// <summary>
+ /// Returns the element at a specified index in a sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Observable sequence to return the element from.</param>
+ /// <param name="index">The zero-based index of the element to retrieve.</param>
+ /// <returns>An observable sequence that produces the element at the specified position in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than zero.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">(Asynchronous) <paramref name="index"/> is greater than or equal to the number of elements in the source sequence.</exception>
+ public static IObservable<TSource> ElementAt<TSource>(this IObservable<TSource> source, int index)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (index < 0)
+ throw new ArgumentOutOfRangeException("index");
+
+ return s_impl.ElementAt<TSource>(source, index);
+ }
+
+ #endregion
+
+ #region + ElementAtOrDefault +
+
+ /// <summary>
+ /// Returns the element at a specified index in a sequence or a default value if the index is out of range.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Observable sequence to return the element from.</param>
+ /// <param name="index">The zero-based index of the element to retrieve.</param>
+ /// <returns>An observable sequence that produces the element at the specified position in the source sequence, or a default value if the index is outside the bounds of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than zero.</exception>
+ public static IObservable<TSource> ElementAtOrDefault<TSource>(this IObservable<TSource> source, int index)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (index < 0)
+ throw new ArgumentOutOfRangeException("index");
+
+ return s_impl.ElementAtOrDefault<TSource>(source, index);
+ }
+
+ #endregion
+
+ #region + FirstAsync +
+
+ /// <summary>
+ /// Returns the first element of an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>Sequence containing the first element in the observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ public static IObservable<TSource> FirstAsync<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.FirstAsync<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the first element of an observable sequence that satisfies the condition in the predicate.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>Sequence containing the first element in the observable sequence that satisfies the condition in the predicate.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) No element satisfies the condition in the predicate. -or- The source sequence is empty.</exception>
+ public static IObservable<TSource> FirstAsync<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.FirstAsync<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + FirstOrDefaultAsync +
+
+ /// <summary>
+ /// Returns the first element of an observable sequence, or a default value if no such element exists.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>Sequence containing the first element in the observable sequence, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> FirstOrDefaultAsync<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.FirstOrDefaultAsync<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the first element of an observable sequence that satisfies the condition in the predicate, or a default value if no such element exists.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>Sequence containing the first element in the observable sequence that satisfies the condition in the predicate, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ public static IObservable<TSource> FirstOrDefaultAsync<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.FirstOrDefaultAsync<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + IsEmpty +
+
+ /// <summary>
+ /// Determines whether an observable sequence is empty.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to check for emptiness.</param>
+ /// <returns>An observable sequence containing a single element determining whether the source sequence is empty.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<bool> IsEmpty<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.IsEmpty<TSource>(source);
+ }
+
+ #endregion
+
+ #region + LastAsync +
+
+ /// <summary>
+ /// Returns the last element of an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>Sequence containing the last element in the observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
+ public static IObservable<TSource> LastAsync<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.LastAsync<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the last element of an observable sequence that satisfies the condition in the predicate.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>Sequence containing the last element in the observable sequence that satisfies the condition in the predicate.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) No element satisfies the condition in the predicate. -or- The source sequence is empty.</exception>
+ public static IObservable<TSource> LastAsync<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.LastAsync<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + LastOrDefaultAsync +
+
+ /// <summary>
+ /// Returns the last element of an observable sequence, or a default value if no such element exists.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>Sequence containing the last element in the observable sequence, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> LastOrDefaultAsync<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.LastOrDefaultAsync<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the last element of an observable sequence that satisfies the condition in the predicate, or a default value if no such element exists.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>Sequence containing the last element in the observable sequence that satisfies the condition in the predicate, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ public static IObservable<TSource> LastOrDefaultAsync<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.LastOrDefaultAsync<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + LongCount +
+
+ /// <summary>
+ /// Returns an observable sequence containing an <see cref="T:System.Int64" /> that represents the total number of elements in an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence that contains elements to be counted.</param>
+ /// <returns>An observable sequence containing a single element with the number of elements in the input sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The number of elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long> LongCount<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.LongCount<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence containing an <see cref="T:System.Int64" /> that represents how many elements in the specified observable sequence satisfy a condition.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence that contains elements to be counted.</param>
+ /// <param name="predicate">A function to test each element for a condition.</param>
+ /// <returns>An observable sequence containing a single element with a number that represents how many elements in the input sequence satisfy the condition in the predicate function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long> LongCount<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.LongCount<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + Max +
+
+ /// <summary>
+ /// Returns the maximum element in an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to determine the maximum element of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum element in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TSource> Max<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence according to the specified comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to determine the maximum element of.</param>
+ /// <param name="comparer">Comparer used to compare elements.</param>
+ /// <returns>An observable sequence containing a single element with the maximum element in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TSource> Max<TSource>(this IObservable<TSource> source, IComparer<TSource> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.Max<TSource>(source, comparer);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence of <see cref="T:System.Double" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Double" /> values to determine the maximum value of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Max(this IObservable<double> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max(source);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence of <see cref="T:System.Single" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Single" /> values to determine the maximum value of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float> Max(this IObservable<float> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max(source);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence of <see cref="T:System.Decimal" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Decimal" /> values to determine the maximum value of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal> Max(this IObservable<decimal> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max(source);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence of <see cref="T:System.Int32" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Int32" /> values to determine the maximum value of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int> Max(this IObservable<int> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max(source);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence of <see cref="T:System.Int64" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Int64" /> values to determine the maximum value of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long> Max(this IObservable<long> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max(source);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence of nullable <see cref="T:System.Double" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Double" /> values to determine the maximum value of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Max(this IObservable<double?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max(source);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence of nullable <see cref="T:System.Single" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Single" /> values to determine the maximum value of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float?> Max(this IObservable<float?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max(source);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence of nullable <see cref="T:System.Decimal" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Decimal" /> values to determine the maximum value of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal?> Max(this IObservable<decimal?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max(source);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence of nullable <see cref="T:System.Int32" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Int32" /> values to determine the maximum value of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int?> Max(this IObservable<int?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max(source);
+ }
+
+ /// <summary>
+ /// Returns the maximum value in an observable sequence of nullable <see cref="T:System.Int64" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Int64" /> values to determine the maximum value of.</param>
+ /// <returns>An observable sequence containing a single element with the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long?> Max(this IObservable<long?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Max(source);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the objects derived from the elements in the source sequence to determine the maximum of.</typeparam>
+ /// <param name="source">An observable sequence to determine the mimimum element of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value that corresponds to the maximum element in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TResult> Max<TSource, TResult>(this IObservable<TSource> source, Func<TSource, TResult> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource, TResult>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum value according to the specified comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the objects derived from the elements in the source sequence to determine the maximum of.</typeparam>
+ /// <param name="source">An observable sequence to determine the mimimum element of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <param name="comparer">Comparer used to compare elements.</param>
+ /// <returns>An observable sequence containing a single element with the value that corresponds to the maximum element in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TResult> Max<TSource, TResult>(this IObservable<TSource> source, Func<TSource, TResult> selector, IComparer<TResult> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.Max<TSource, TResult>(source, selector, comparer);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum <see cref="T:System.Double" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the maximum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Double" /> that corresponds to the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Max<TSource>(this IObservable<TSource> source, Func<TSource, double> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum <see cref="T:System.Single" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the maximum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Single" /> that corresponds to the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float> Max<TSource>(this IObservable<TSource> source, Func<TSource, float> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum <see cref="T:System.Decimal" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the maximum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Decimal" /> that corresponds to the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal> Max<TSource>(this IObservable<TSource> source, Func<TSource, decimal> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum <see cref="T:System.Int32" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the maximum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Int32" /> that corresponds to the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int> Max<TSource>(this IObservable<TSource> source, Func<TSource, int> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum <see cref="T:System.Int64" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the maximum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Int64" /> that corresponds to the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long> Max<TSource>(this IObservable<TSource> source, Func<TSource, long> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum nullable <see cref="T:System.Double" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the maximum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Nullable&lt;System.Double&gt;" /> that corresponds to the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Max<TSource>(this IObservable<TSource> source, Func<TSource, double?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum nullable <see cref="T:System.Single" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the maximum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Nullable&lt;System.Single&gt;" /> that corresponds to the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float?> Max<TSource>(this IObservable<TSource> source, Func<TSource, float?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum nullable <see cref="T:System.Decimal" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the maximum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Nullable&lt;System.Decimal&gt;" /> that corresponds to the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal?> Max<TSource>(this IObservable<TSource> source, Func<TSource, decimal?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum nullable <see cref="T:System.Int32" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the maximum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Nullable&lt;System.Int32&gt;" /> that corresponds to the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int?> Max<TSource>(this IObservable<TSource> source, Func<TSource, int?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the maximum nullable <see cref="T:System.Int64" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the maximum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Nullable&lt;System.Int64&gt;" /> that corresponds to the maximum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long?> Max<TSource>(this IObservable<TSource> source, Func<TSource, long?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Max<TSource>(source, selector);
+ }
+
+ #endregion
+
+ #region + MaxBy +
+
+ /// <summary>
+ /// Returns the elements in an observable sequence with the maximum key value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to get the maximum elements for.</param>
+ /// <param name="keySelector">Key selector function.</param>
+ /// <returns>An observable sequence containing a list of zero or more elements that have a maximum key value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<IList<TSource>> MaxBy<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+
+ return s_impl.MaxBy<TSource, TKey>(source, keySelector);
+ }
+
+ /// <summary>
+ /// Returns the elements in an observable sequence with the maximum key value according to the specified comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to get the maximum elements for.</param>
+ /// <param name="keySelector">Key selector function.</param>
+ /// <param name="comparer">Comparer used to compare key values.</param>
+ /// <returns>An observable sequence containing a list of zero or more elements that have a maximum key value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<IList<TSource>> MaxBy<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.MaxBy<TSource, TKey>(source, keySelector, comparer);
+ }
+
+ #endregion
+
+ #region + Min +
+
+ /// <summary>
+ /// Returns the minimum element in an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to determine the mimimum element of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum element in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TSource> Min<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the minimum element in an observable sequence according to the specified comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to determine the mimimum element of.</param>
+ /// <param name="comparer">Comparer used to compare elements.</param>
+ /// <returns>An observable sequence containing a single element with the minimum element in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TSource> Min<TSource>(this IObservable<TSource> source, IComparer<TSource> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.Min<TSource>(source, comparer);
+ }
+
+ /// <summary>
+ /// Returns the minimum value in an observable sequence of <see cref="T:System.Double" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Double" /> values to determine the minimum value of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Min(this IObservable<double> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min(source);
+ }
+
+ /// <summary>
+ /// Returns the minimum value in an observable sequence of <see cref="T:System.Single" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Single" /> values to determine the minimum value of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float> Min(this IObservable<float> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min(source);
+ }
+
+ /// <summary>
+ /// Returns the minimum value in an observable sequence of <see cref="T:System.Decimal" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Decimal" /> values to determine the minimum value of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal> Min(this IObservable<decimal> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min(source);
+ }
+
+ /// <summary>
+ /// Returns the minimum value in an observable sequence of <see cref="T:System.Int32" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Int32" /> values to determine the minimum value of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int> Min(this IObservable<int> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min(source);
+ }
+
+ /// <summary>
+ /// Returns the minimum value in an observable sequence of <see cref="T:System.Int64" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Int64" /> values to determine the minimum value of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long> Min(this IObservable<long> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min(source);
+ }
+
+ /// <summary>
+ /// Returns the minimum value in an observable sequence of nullable <see cref="T:System.Double" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Double" /> values to determine the minimum value of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Min(this IObservable<double?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min(source);
+ }
+
+ /// <summary>
+ /// Returns the minimum value in an observable sequence of nullable <see cref="T:System.Single" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Single" /> values to determine the minimum value of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float?> Min(this IObservable<float?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min(source);
+ }
+
+ /// <summary>
+ /// Returns the minimum value in an observable sequence of nullable <see cref="T:System.Decimal" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Decimal" /> values to determine the minimum value of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal?> Min(this IObservable<decimal?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min(source);
+ }
+
+ /// <summary>
+ /// Returns the minimum value in an observable sequence of nullable <see cref="T:System.Int32" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Int32" /> values to determine the minimum value of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int?> Min(this IObservable<int?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min(source);
+ }
+
+ /// <summary>
+ /// Returns the minimum value in an observable sequence of nullable <see cref="T:System.Int64" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Int64" /> values to determine the minimum value of.</param>
+ /// <returns>An observable sequence containing a single element with the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long?> Min(this IObservable<long?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Min(source);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the objects derived from the elements in the source sequence to determine the minimum of.</typeparam>
+ /// <param name="source">An observable sequence to determine the mimimum element of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value that corresponds to the minimum element in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TResult> Min<TSource, TResult>(this IObservable<TSource> source, Func<TSource, TResult> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource, TResult>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum value according to the specified comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the objects derived from the elements in the source sequence to determine the minimum of.</typeparam>
+ /// <param name="source">An observable sequence to determine the mimimum element of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <param name="comparer">Comparer used to compare elements.</param>
+ /// <returns>An observable sequence containing a single element with the value that corresponds to the minimum element in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TResult> Min<TSource, TResult>(this IObservable<TSource> source, Func<TSource, TResult> selector, IComparer<TResult> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.Min<TSource, TResult>(source, selector, comparer);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum <see cref="T:System.Double" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the minimum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Double" /> that corresponds to the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Min<TSource>(this IObservable<TSource> source, Func<TSource, double> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum <see cref="T:System.Single" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the minimum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Single" /> that corresponds to the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float> Min<TSource>(this IObservable<TSource> source, Func<TSource, float> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum <see cref="T:System.Decimal" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the minimum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Decimal" /> that corresponds to the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal> Min<TSource>(this IObservable<TSource> source, Func<TSource, decimal> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum <see cref="T:System.Int32" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the minimum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Int32" /> that corresponds to the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int> Min<TSource>(this IObservable<TSource> source, Func<TSource, int> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum <see cref="T:System.Int64" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the minimum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Int64" /> that corresponds to the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long> Min<TSource>(this IObservable<TSource> source, Func<TSource, long> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum nullable <see cref="T:System.Double" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the minimum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Nullable&lt;System.Double&gt;" /> that corresponds to the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Min<TSource>(this IObservable<TSource> source, Func<TSource, double?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum nullable <see cref="T:System.Single" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the minimum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Nullable&lt;System.Single&gt;" /> that corresponds to the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float?> Min<TSource>(this IObservable<TSource> source, Func<TSource, float?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum nullable <see cref="T:System.Decimal" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the minimum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Nullable&lt;System.Decimal&gt;" /> that corresponds to the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal?> Min<TSource>(this IObservable<TSource> source, Func<TSource, decimal?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum nullable <see cref="T:System.Int32" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the minimum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Nullable&lt;System.Int32&gt;" /> that corresponds to the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int?> Min<TSource>(this IObservable<TSource> source, Func<TSource, int?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Invokes a transform function on each element of a sequence and returns the minimum nullable <see cref="T:System.Int64" /> value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values to determine the minimum value of.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the value of type <see cref="T:System.Nullable&lt;System.Int64&gt;" /> that corresponds to the minimum value in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long?> Min<TSource>(this IObservable<TSource> source, Func<TSource, long?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Min<TSource>(source, selector);
+ }
+
+ #endregion
+
+ #region + MinBy +
+
+ /// <summary>
+ /// Returns the elements in an observable sequence with the minimum key value.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to get the minimum elements for.</param>
+ /// <param name="keySelector">Key selector function.</param>
+ /// <returns>An observable sequence containing a list of zero or more elements that have a minimum key value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<IList<TSource>> MinBy<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+
+ return s_impl.MinBy<TSource, TKey>(source, keySelector);
+ }
+
+ /// <summary>
+ /// Returns the elements in an observable sequence with the minimum key value according to the specified comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to get the minimum elements for.</param>
+ /// <param name="keySelector">Key selector function.</param>
+ /// <param name="comparer">Comparer used to compare key values.</param>
+ /// <returns>An observable sequence containing a list of zero or more elements that have a minimum key value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<IList<TSource>> MinBy<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.MinBy<TSource, TKey>(source, keySelector, comparer);
+ }
+
+ #endregion
+
+ #region + SequenceEqual +
+
+ /// <summary>
+ /// Determines whether two sequences are equal by comparing the elements pairwise.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="first">First observable sequence to compare.</param>
+ /// <param name="second">Second observable sequence to compare.</param>
+ /// <returns>An observable sequence that contains a single element which indicates whether both sequences are of equal length and their corresponding elements are equal according to the default equality comparer for their type.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<bool> SequenceEqual<TSource>(this IObservable<TSource> first, IObservable<TSource> second)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+
+ return s_impl.SequenceEqual<TSource>(first, second);
+ }
+
+ /// <summary>
+ /// Determines whether two sequences are equal by comparing the elements pairwise using a specified equality comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="first">First observable sequence to compare.</param>
+ /// <param name="second">Second observable sequence to compare.</param>
+ /// <param name="comparer">Comparer used to compare elements of both sequences.</param>
+ /// <returns>An observable sequence that contains a single element which indicates whether both sequences are of equal length and their corresponding elements are equal according to the specified equality comparer.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<bool> SequenceEqual<TSource>(this IObservable<TSource> first, IObservable<TSource> second, IEqualityComparer<TSource> comparer)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.SequenceEqual<TSource>(first, second, comparer);
+ }
+
+ /// <summary>
+ /// Determines whether an observable and enumerable sequence are equal by comparing the elements pairwise.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="first">First observable sequence to compare.</param>
+ /// <param name="second">Second observable sequence to compare.</param>
+ /// <returns>An observable sequence that contains a single element which indicates whether both sequences are of equal length and their corresponding elements are equal according to the default equality comparer for their type.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<bool> SequenceEqual<TSource>(this IObservable<TSource> first, IEnumerable<TSource> second)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+
+ return s_impl.SequenceEqual<TSource>(first, second);
+ }
+
+ /// <summary>
+ /// Determines whether an observable and enumerable sequence are equal by comparing the elements pairwise using a specified equality comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="first">First observable sequence to compare.</param>
+ /// <param name="second">Second observable sequence to compare.</param>
+ /// <param name="comparer">Comparer used to compare elements of both sequences.</param>
+ /// <returns>An observable sequence that contains a single element which indicates whether both sequences are of equal length and their corresponding elements are equal according to the specified equality comparer.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<bool> SequenceEqual<TSource>(this IObservable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.SequenceEqual<TSource>(first, second, comparer);
+ }
+
+ #endregion
+
+ #region + SingleAsync +
+
+ /// <summary>
+ /// Returns the only element of an observable sequence, and reports an exception if there is not exactly one element in the observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>Sequence containing the single element in the observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence contains more than one element. -or- The source sequence is empty.</exception>
+ public static IObservable<TSource> SingleAsync<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.SingleAsync<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the only element of an observable sequence that satisfies the condition in the predicate, and reports an exception if there is not exactly one element in the observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>Sequence containing the single element in the observable sequence that satisfies the condition in the predicate.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) No element satisfies the condition in the predicate. -or- More than one element satisfies the condition in the predicate. -or- The source sequence is empty.</exception>
+ public static IObservable<TSource> SingleAsync<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.SingleAsync<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + SingleOrDefaultAsync +
+
+ /// <summary>
+ /// Returns the only element of an observable sequence, or a default value if the observable sequence is empty; this method reports an exception if there is more than one element in the observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>Sequence containing the single element in the observable sequence, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence contains more than one element.</exception>
+ public static IObservable<TSource> SingleOrDefaultAsync<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.SingleOrDefaultAsync<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the only element of an observable sequence that matches the predicate, or a default value if no such element exists; this method reports an exception if there is more than one element in the observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>Sequence containing the single element in the observable sequence that satisfies the condition in the predicate, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">(Asynchronous) The sequence contains more than one element that satisfies the condition in the predicate.</exception>
+ public static IObservable<TSource> SingleOrDefaultAsync<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.SingleOrDefaultAsync<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + Sum +
+
+ /// <summary>
+ /// Computes the sum of a sequence of <see cref="T:System.Double" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Double" /> values to calculate the sum of.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Sum(this IObservable<double> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Sum(source);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of <see cref="T:System.Single" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Single" /> values to calculate the sum of.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float> Sum(this IObservable<float> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Sum(source);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of <see cref="T:System.Decimal" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Decimal" /> values to calculate the sum of.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Decimal.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal> Sum(this IObservable<decimal> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Sum(source);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of <see cref="T:System.Int32" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Int32" /> values to calculate the sum of.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Int32.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int> Sum(this IObservable<int> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Sum(source);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of <see cref="T:System.Int64" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of <see cref="T:System.Int64" /> values to calculate the sum of.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long> Sum(this IObservable<long> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Sum(source);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of nullable <see cref="T:System.Double" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Double" /> values to calculate the sum of.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Sum(this IObservable<double?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Sum(source);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of nullable <see cref="T:System.Single" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Single" /> values to calculate the sum of.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float?> Sum(this IObservable<float?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Sum(source);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of nullable <see cref="T:System.Decimal" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Decimal" /> values to calculate the sum of.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Decimal.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal?> Sum(this IObservable<decimal?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Sum(source);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of nullable <see cref="T:System.Int32" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Int32" /> values to calculate the sum of.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Int32.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int?> Sum(this IObservable<int?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Sum(source);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of nullable <see cref="T:System.Int64" /> values.
+ /// </summary>
+ /// <param name="source">A sequence of nullable <see cref="T:System.Int64" /> values to calculate the sum of.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long?> Sum(this IObservable<long?> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Sum(source);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of <see cref="T:System.Double" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values that are used to calculate a sum.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double> Sum<TSource>(this IObservable<TSource> source, Func<TSource, double> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Sum<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of <see cref="T:System.Single" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values that are used to calculate a sum.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float> Sum<TSource>(this IObservable<TSource> source, Func<TSource, float> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Sum<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of <see cref="T:System.Decimal" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values that are used to calculate a sum.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Decimal.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal> Sum<TSource>(this IObservable<TSource> source, Func<TSource, decimal> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Sum<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of <see cref="T:System.Int32" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values that are used to calculate a sum.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Int32.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int> Sum<TSource>(this IObservable<TSource> source, Func<TSource, int> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Sum<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of <see cref="T:System.Int64" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values that are used to calculate a sum.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long> Sum<TSource>(this IObservable<TSource> source, Func<TSource, long> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Sum<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of nullable <see cref="T:System.Double" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values that are used to calculate a sum.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<double?> Sum<TSource>(this IObservable<TSource> source, Func<TSource, double?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Sum<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of nullable <see cref="T:System.Single" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values that are used to calculate a sum.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<float?> Sum<TSource>(this IObservable<TSource> source, Func<TSource, float?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Sum<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of nullable <see cref="T:System.Decimal" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values that are used to calculate a sum.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Decimal.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<decimal?> Sum<TSource>(this IObservable<TSource> source, Func<TSource, decimal?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Sum<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of nullable <see cref="T:System.Int32" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values that are used to calculate a sum.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Int32.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<int?> Sum<TSource>(this IObservable<TSource> source, Func<TSource, int?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Sum<TSource>(source, selector);
+ }
+
+ /// <summary>
+ /// Computes the sum of a sequence of nullable <see cref="T:System.Int64" /> values that are obtained by invoking a transform function on each element of the input sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence of values that are used to calculate a sum.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence containing a single element with the sum of the values in the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="OverflowException">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref="M:System.Int64.MaxValue"/>.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<long?> Sum<TSource>(this IObservable<TSource> source, Func<TSource, long?> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Sum<TSource>(source, selector);
+ }
+
+ #endregion
+
+ #region + ToArray +
+
+ /// <summary>
+ /// Creates an array from an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">The source observable sequence to get an array of elements for.</param>
+ /// <returns>An observable sequence containing a single element with an array containing all the elements of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<TSource[]> ToArray<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.ToArray<TSource>(source);
+ }
+
+ #endregion
+
+ #region + ToDictionary +
+
+ /// <summary>
+ /// Creates a dictionary from an observable sequence according to a specified key selector function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the dictionary key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to create a dictionary for.</param>
+ /// <param name="keySelector">A function to extract a key from each element.</param>
+ /// <returns>An observable sequence containing a single element with a dictionary mapping unique key values onto the corresponding source sequence's element.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<IDictionary<TKey, TSource>> ToDictionary<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+
+ return s_impl.ToDictionary<TSource, TKey>(source, keySelector);
+ }
+
+ /// <summary>
+ /// Creates a dictionary from an observable sequence according to a specified key selector function, and a comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the dictionary key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to create a dictionary for.</param>
+ /// <param name="keySelector">A function to extract a key from each element.</param>
+ /// <param name="comparer">An equality comparer to compare keys.</param>
+ /// <returns>An observable sequence containing a single element with a dictionary mapping unique key values onto the corresponding source sequence's element.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<IDictionary<TKey, TSource>> ToDictionary<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.ToDictionary<TSource, TKey>(source, keySelector, comparer);
+ }
+
+ /// <summary>
+ /// Creates a dictionary from an observable sequence according to a specified key selector function, and an element selector function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the dictionary key computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TElement">The type of the dictionary value computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to create a dictionary for.</param>
+ /// <param name="keySelector">A function to extract a key from each element.</param>
+ /// <param name="elementSelector">A transform function to produce a result element value from each element.</param>
+ /// <returns>An observable sequence containing a single element with a dictionary mapping unique key values onto the corresponding source sequence's element.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<IDictionary<TKey, TElement>> ToDictionary<TSource, TKey, TElement>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (elementSelector == null)
+ throw new ArgumentNullException("elementSelector");
+
+ return s_impl.ToDictionary<TSource, TKey, TElement>(source, keySelector, elementSelector);
+ }
+
+ /// <summary>
+ /// Creates a dictionary from an observable sequence according to a specified key selector function, a comparer, and an element selector function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the dictionary key computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TElement">The type of the dictionary value computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to create a dictionary for.</param>
+ /// <param name="keySelector">A function to extract a key from each element.</param>
+ /// <param name="elementSelector">A transform function to produce a result element value from each element.</param>
+ /// <param name="comparer">An equality comparer to compare keys.</param>
+ /// <returns>An observable sequence containing a single element with a dictionary mapping unique key values onto the corresponding source sequence's element.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<IDictionary<TKey, TElement>> ToDictionary<TSource, TKey, TElement>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (elementSelector == null)
+ throw new ArgumentNullException("elementSelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.ToDictionary<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
+ }
+
+ #endregion
+
+ #region + ToList +
+
+ /// <summary>
+ /// Creates a list from an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">The source observable sequence to get a list of elements for.</param>
+ /// <returns>An observable sequence containing a single element with a list containing all the elements of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<IList<TSource>> ToList<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.ToList<TSource>(source);
+ }
+
+ #endregion
+
+ #region + ToLookup +
+
+ /// <summary>
+ /// Creates a lookup from an observable sequence according to a specified key selector function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the lookup key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to create a lookup for.</param>
+ /// <param name="keySelector">A function to extract a key from each element.</param>
+ /// <returns>An observable sequence containing a single element with a lookup mapping unique key values onto the corresponding source sequence's elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<ILookup<TKey, TSource>> ToLookup<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+
+ return s_impl.ToLookup<TSource, TKey>(source, keySelector);
+ }
+
+ /// <summary>
+ /// Creates a lookup from an observable sequence according to a specified key selector function, and a comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the lookup key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to create a lookup for.</param>
+ /// <param name="keySelector">A function to extract a key from each element.</param>
+ /// <param name="comparer">An equality comparer to compare keys.</param>
+ /// <returns>An observable sequence containing a single element with a lookup mapping unique key values onto the corresponding source sequence's elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<ILookup<TKey, TSource>> ToLookup<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.ToLookup<TSource, TKey>(source, keySelector, comparer);
+ }
+
+ /// <summary>
+ /// Creates a lookup from an observable sequence according to a specified key selector function, and an element selector function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the lookup key computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TElement">The type of the lookup value computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to create a lookup for.</param>
+ /// <param name="keySelector">A function to extract a key from each element.</param>
+ /// <param name="elementSelector">A transform function to produce a result element value from each element.</param>
+ /// <returns>An observable sequence containing a single element with a lookup mapping unique key values onto the corresponding source sequence's elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<ILookup<TKey, TElement>> ToLookup<TSource, TKey, TElement>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (elementSelector == null)
+ throw new ArgumentNullException("elementSelector");
+
+ return s_impl.ToLookup<TSource, TKey, TElement>(source, keySelector, elementSelector);
+ }
+
+ /// <summary>
+ /// Creates a lookup from an observable sequence according to a specified key selector function, a comparer, and an element selector function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the lookup key computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TElement">The type of the lookup value computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to create a lookup for.</param>
+ /// <param name="keySelector">A function to extract a key from each element.</param>
+ /// <param name="elementSelector">A transform function to produce a result element value from each element.</param>
+ /// <param name="comparer">An equality comparer to compare keys.</param>
+ /// <returns>An observable sequence containing a single element with a lookup mapping unique key values onto the corresponding source sequence's elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
+ public static IObservable<ILookup<TKey, TElement>> ToLookup<TSource, TKey, TElement>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (elementSelector == null)
+ throw new ArgumentNullException("elementSelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.ToLookup<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Async.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Async.cs
new file mode 100644
index 0000000..8f74075
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Async.cs
@@ -0,0 +1,2802 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Reactive.Concurrency;
+using System.Threading;
+
+#if !NO_TPL
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region FromAsyncPattern
+
+ #region Func
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<IObservable<TResult>> FromAsyncPattern<TResult>(Func<AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, IObservable<TResult>> FromAsyncPattern<TArg1, TResult>(Func<TArg1, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TResult>(Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TResult>(begin, end);
+ }
+
+#if !NO_LARGEARITY
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TResult>(Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TResult>(Func<TArg1, TArg2, TArg3, TArg4, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the end delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, IObservable<TResult>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult>(begin, end);
+ }
+#endif
+
+ #endregion
+
+ #region Action
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<IObservable<Unit>> FromAsyncPattern(Func<AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, IObservable<Unit>> FromAsyncPattern<TArg1>(Func<TArg1, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2>(Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2>(begin, end);
+ }
+
+#if !NO_LARGEARITY
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3>(Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4>(Func<TArg1, TArg2, TArg3, TArg4, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13>(begin, end);
+ }
+
+ /// <summary>
+ /// Converts a Begin/End invoke function pair into an asynchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the begin delegate.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the begin delegate.</typeparam>
+ /// <param name="begin">The delegate that begins the asynchronous operation.</param>
+ /// <param name="end">The delegate that ends the asynchronous operation.</param>
+ /// <returns>Function that can be used to start the asynchronous operation and retrieve the result (represented as a Unit value) as an observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="begin"/> or <paramref name="end"/> is null.</exception>
+ /// <remarks>Each invocation of the resulting function will cause the asynchronous operation to be started. Subscription to the resulting sequence has no observable side-effect, and each subscription will produce the asynchronous operation's result.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_TASK_FROMASYNCPATTERN)]
+#endif
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, IObservable<Unit>> FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ if (begin == null)
+ throw new ArgumentNullException("begin");
+ if (end == null)
+ throw new ArgumentNullException("end");
+
+ return s_impl.FromAsyncPattern<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14>(begin, end);
+ }
+#endif
+
+ #endregion
+
+ #endregion
+
+ #region Start[Async]
+
+ #region Func
+
+ /// <summary>
+ /// Invokes the specified function asynchronously, surfacing the result through an observable sequence.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to run asynchronously.</param>
+ /// <returns>An observable sequence exposing the function's result value, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ /// <remarks>
+ /// <list type="bullet">
+ /// <item><description>The function is called immediately, not during the subscription of the resulting sequence.</description></item>
+ /// <item><description>Multiple subscriptions to the resulting sequence can observe the function's result.</description></item>
+ /// </list>
+ /// </remarks>
+ public static IObservable<TResult> Start<TResult>(Func<TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.Start<TResult>(function);
+ }
+
+ /// <summary>
+ /// Invokes the specified function asynchronously on the specified scheduler, surfacing the result through an observable sequence
+ /// </summary>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to run asynchronously.</param>
+ /// <param name="scheduler">Scheduler to run the function on.</param>
+ /// <returns>An observable sequence exposing the function's result value, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <list type="bullet">
+ /// <item><description>The function is called immediately, not during the subscription of the resulting sequence.</description></item>
+ /// <item><description>Multiple subscriptions to the resulting sequence can observe the function's result.</description></item>
+ /// </list>
+ /// </remarks>
+ public static IObservable<TResult> Start<TResult>(Func<TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Start<TResult>(function, scheduler);
+ }
+
+#if !NO_TPL
+ /// <summary>
+ /// Invokes the asynchronous function, surfacing the result through an observable sequence.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the result returned by the asynchronous function.</typeparam>
+ /// <param name="functionAsync">Asynchronous function to run.</param>
+ /// <returns>An observable sequence exposing the function's result value, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="functionAsync"/> is null.</exception>
+ /// <remarks>
+ /// <list type="bullet">
+ /// <item><description>The function is started immediately, not during the subscription of the resulting sequence.</description></item>
+ /// <item><description>Multiple subscriptions to the resulting sequence can observe the function's result.</description></item>
+ /// </list>
+ /// </remarks>
+ public static IObservable<TResult> StartAsync<TResult>(Func<Task<TResult>> functionAsync)
+ {
+ if (functionAsync == null)
+ throw new ArgumentNullException("functionAsync");
+
+ return s_impl.StartAsync<TResult>(functionAsync);
+ }
+
+ /// <summary>
+ /// Invokes the asynchronous function, surfacing the result through an observable sequence.
+ /// The CancellationToken is shared by all subscriptions on the resulting observable sequence. See the remarks section for more information.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the result returned by the asynchronous function.</typeparam>
+ /// <param name="functionAsync">Asynchronous function to run.</param>
+ /// <returns>An observable sequence exposing the function's result value, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="functionAsync"/> is null.</exception>
+ /// <remarks>
+ /// <list type="bullet">
+ /// <item><description>The function is started immediately, not during the subscription of the resulting sequence.</description></item>
+ /// <item><description>Multiple subscriptions to the resulting sequence can observe the function's result.</description></item>
+ /// <item><description>
+ /// If any subscription to the resulting sequence is disposed, the CancellationToken is set. The observer associated to the disposed
+ /// subscription won't see the TaskCanceledException, but other observers will. You can protect against this using the Catch operator.
+ /// Be careful when handing out the resulting sequence because of this behavior. The most common use is to have a single subscription
+ /// to the resulting sequence, which controls the CancellationToken state. Alternatively, you can control subscription behavior using
+ /// multicast operators.
+ /// </description></item>
+ /// </list>
+ /// </remarks>
+ public static IObservable<TResult> StartAsync<TResult>(Func<CancellationToken, Task<TResult>> functionAsync)
+ {
+ if (functionAsync == null)
+ throw new ArgumentNullException("functionAsync");
+
+ return s_impl.StartAsync<TResult>(functionAsync);
+ }
+#endif
+
+ #endregion
+
+ #region Action
+
+ /// <summary>
+ /// Invokes the action asynchronously, surfacing the result through an observable sequence.
+ /// </summary>
+ /// <param name="action">Action to run asynchronously.</param>
+ /// <returns>An observable sequence exposing a Unit value upon completion of the action, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ /// <remarks>
+ /// <list type="bullet">
+ /// <item><description>The action is called immediately, not during the subscription of the resulting sequence.</description></item>
+ /// <item><description>Multiple subscriptions to the resulting sequence can observe the action's outcome.</description></item>
+ /// </list>
+ /// </remarks>
+ public static IObservable<Unit> Start(Action action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.Start(action);
+ }
+
+ /// <summary>
+ /// Invokes the action asynchronously on the specified scheduler, surfacing the result through an observable sequence.
+ /// </summary>
+ /// <param name="action">Action to run asynchronously.</param>
+ /// <param name="scheduler">Scheduler to run the action on.</param>
+ /// <returns>An observable sequence exposing a Unit value upon completion of the action, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <list type="bullet">
+ /// <item><description>The action is called immediately, not during the subscription of the resulting sequence.</description></item>
+ /// <item><description>Multiple subscriptions to the resulting sequence can observe the action's outcome.</description></item>
+ /// </list>
+ /// </remarks>
+ public static IObservable<Unit> Start(Action action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Start(action, scheduler);
+ }
+
+#if !NO_TPL
+ /// <summary>
+ /// Invokes the asynchronous action, surfacing the result through an observable sequence.
+ /// </summary>
+ /// <param name="actionAsync">Asynchronous action to run.</param>
+ /// <returns>An observable sequence exposing a Unit value upon completion of the action, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="actionAsync"/> is null.</exception>
+ /// <remarks>
+ /// <list type="bullet">
+ /// <item><description>The action is started immediately, not during the subscription of the resulting sequence.</description></item>
+ /// <item><description>Multiple subscriptions to the resulting sequence can observe the action's outcome.</description></item>
+ /// </list>
+ /// </remarks>
+ public static IObservable<Unit> StartAsync(Func<Task> actionAsync)
+ {
+ if (actionAsync == null)
+ throw new ArgumentNullException("actionAsync");
+
+ return s_impl.StartAsync(actionAsync);
+ }
+
+ /// <summary>
+ /// Invokes the asynchronous action, surfacing the result through an observable sequence.
+ /// The CancellationToken is shared by all subscriptions on the resulting observable sequence. See the remarks section for more information.
+ /// </summary>
+ /// <param name="actionAsync">Asynchronous action to run.</param>
+ /// <returns>An observable sequence exposing a Unit value upon completion of the action, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="actionAsync"/> is null.</exception>
+ /// <remarks>
+ /// <list type="bullet">
+ /// <item><description>The action is started immediately, not during the subscription of the resulting sequence.</description></item>
+ /// <item><description>Multiple subscriptions to the resulting sequence can observe the action's outcome.</description></item>
+ /// <item><description>
+ /// If any subscription to the resulting sequence is disposed, the CancellationToken is set. The observer associated to the disposed
+ /// subscription won't see the TaskCanceledException, but other observers will. You can protect against this using the Catch operator.
+ /// Be careful when handing out the resulting sequence because of this behavior. The most common use is to have a single subscription
+ /// to the resulting sequence, which controls the CancellationToken state. Alternatively, you can control subscription behavior using
+ /// multicast operators.
+ /// </description></item>
+ /// </list>
+ /// </remarks>
+ public static IObservable<Unit> StartAsync(Func<CancellationToken, Task> actionAsync)
+ {
+ if (actionAsync == null)
+ throw new ArgumentNullException("actionAsync");
+
+ return s_impl.StartAsync(actionAsync);
+ }
+#endif
+
+ #endregion
+
+ #endregion
+
+ #region FromAsync
+
+#if !NO_TPL
+
+ #region Func
+
+ /// <summary>
+ /// Converts to asynchronous function into an observable sequence. Each subscription to the resulting sequence causes the function to be started.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the result returned by the asynchronous function.</typeparam>
+ /// <param name="functionAsync">Asynchronous function to convert.</param>
+ /// <returns>An observable sequence exposing the result of invoking the function, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="functionAsync"/> is null.</exception>
+ public static IObservable<TResult> FromAsync<TResult>(Func<Task<TResult>> functionAsync)
+ {
+ return s_impl.FromAsync<TResult>(functionAsync);
+ }
+
+ /// <summary>
+ /// Converts to asynchronous function into an observable sequence. Each subscription to the resulting sequence causes the function to be started.
+ /// The CancellationToken passed to the asynchronous function is tied to the observable sequence's subscription that triggered the function's invocation and can be used for best-effort cancellation.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the result returned by the asynchronous function.</typeparam>
+ /// <param name="functionAsync">Asynchronous function to convert.</param>
+ /// <returns>An observable sequence exposing the result of invoking the function, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="functionAsync"/> is null.</exception>
+ /// <remarks>When a subscription to the resulting sequence is disposed, the CancellationToken that was fed to the asynchronous function will be signaled.</remarks>
+ public static IObservable<TResult> FromAsync<TResult>(Func<CancellationToken, Task<TResult>> functionAsync)
+ {
+ return s_impl.FromAsync<TResult>(functionAsync);
+ }
+
+ #endregion
+
+ #region Action
+
+ /// <summary>
+ /// Converts to asynchronous action into an observable sequence. Each subscription to the resulting sequence causes the action to be started.
+ /// </summary>
+ /// <param name="actionAsync">Asynchronous action to convert.</param>
+ /// <returns>An observable sequence exposing a Unit value upon completion of the action, or an exception.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="actionAsync"/> is null.</exception>
+ public static IObservable<Unit> FromAsync(Func<Task> actionAsync)
+ {
+ return s_impl.FromAsync(actionAsync);
+ }
+
+ /// <summary>
+ /// Converts to asynchronous action into an observable sequence. Each subscription to the resulting sequence causes the action to be started.
+ /// The CancellationToken passed to the asynchronous action is tied to the observable sequence's subscription that triggered the action's invocation and can be used for best-effort cancellation.
+ /// </summary>
+ /// <param name="actionAsync">Asynchronous action to convert.</param>
+ /// <returns>An observable sequence exposing a Unit value upon completion of the action, or an exception.</returns>
+ /// <remarks>When a subscription to the resulting sequence is disposed, the CancellationToken that was fed to the asynchronous function will be signaled.</remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="actionAsync"/> is null.</exception>
+ public static IObservable<Unit> FromAsync(Func<CancellationToken, Task> actionAsync)
+ {
+ return s_impl.FromAsync(actionAsync);
+ }
+
+ #endregion
+
+#endif
+
+ #endregion
+
+ #region ToAsync
+
+ #region Func
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<IObservable<TResult>> ToAsync<TResult>(this Func<TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<IObservable<TResult>> ToAsync<TResult>(this Func<TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, IObservable<TResult>> ToAsync<TArg1, TResult>(this Func<TArg1, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, IObservable<TResult>> ToAsync<TArg1, TResult>(this Func<TArg1, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, IObservable<TResult>> ToAsync<TArg1, TArg2, TResult>(this Func<TArg1, TArg2, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, IObservable<TResult>> ToAsync<TArg1, TArg2, TResult>(this Func<TArg1, TArg2, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TResult>(this Func<TArg1, TArg2, TArg3, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TResult>(this Func<TArg1, TArg2, TArg3, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TResult>(function, scheduler);
+ }
+
+#if !NO_LARGEARITY
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg15">The type of the fifteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg15">The type of the fifteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TResult>(function, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg15">The type of the fifteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg16">The type of the sixteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, TResult> function)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, TResult>(function);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the function.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the function.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the function.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the function.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg15">The type of the fifteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TArg16">The type of the sixteenth argument passed to the function.</typeparam>
+ /// <typeparam name="TResult">The type of the result returned by the function.</typeparam>
+ /// <param name="function">Function to convert to an asynchronous function.</param>
+ /// <param name="scheduler">Scheduler to invoke the original function on.</param>
+ /// <returns>Asynchronous function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="function"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, IObservable<TResult>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, TResult>(this Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, TResult> function, IScheduler scheduler)
+ {
+ if (function == null)
+ throw new ArgumentNullException("function");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, TResult>(function, scheduler);
+ }
+#endif
+
+ #endregion
+
+ #region Action
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<IObservable<Unit>> ToAsync(this Action action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<IObservable<Unit>> ToAsync(this Action action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, IObservable<Unit>> ToAsync<TArg1>(this Action<TArg1> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, IObservable<Unit>> ToAsync<TArg1>(this Action<TArg1> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, IObservable<Unit>> ToAsync<TArg1, TArg2>(this Action<TArg1, TArg2> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, IObservable<Unit>> ToAsync<TArg1, TArg2>(this Action<TArg1, TArg2> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3>(this Action<TArg1, TArg2, TArg3> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3>(this Action<TArg1, TArg2, TArg3> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4>(this Action<TArg1, TArg2, TArg3, TArg4> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4>(this Action<TArg1, TArg2, TArg3, TArg4> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4>(action, scheduler);
+ }
+
+#if !NO_LARGEARITY
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg15">The type of the fifteenth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg15">The type of the fifteenth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15>(action, scheduler);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the default scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg15">The type of the fifteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg16">The type of the sixteenth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16>(action);
+ }
+
+ /// <summary>
+ /// Converts the function into an asynchronous action. Each invocation of the resulting asynchronous action causes an invocation of the original synchronous action on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TArg1">The type of the first argument passed to the action.</typeparam>
+ /// <typeparam name="TArg2">The type of the second argument passed to the action.</typeparam>
+ /// <typeparam name="TArg3">The type of the third argument passed to the action.</typeparam>
+ /// <typeparam name="TArg4">The type of the fourth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg5">The type of the fifth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg6">The type of the sixth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg7">The type of the seventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg8">The type of the eighth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg9">The type of the ninth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg10">The type of the tenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg11">The type of the eleventh argument passed to the action.</typeparam>
+ /// <typeparam name="TArg12">The type of the twelfth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg13">The type of the thirteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg14">The type of the fourteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg15">The type of the fifteenth argument passed to the action.</typeparam>
+ /// <typeparam name="TArg16">The type of the sixteenth argument passed to the action.</typeparam>
+ /// <param name="action">Action to convert to an asynchronous action.</param>
+ /// <param name="scheduler">Scheduler to invoke the original action on.</param>
+ /// <returns>Asynchronous action.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="scheduler"/> is null.</exception>
+ public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, IObservable<Unit>> ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16>(this Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16> action, IScheduler scheduler)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToAsync<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16>(action, scheduler);
+ }
+#endif
+
+ #endregion
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Awaiter.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Awaiter.cs
new file mode 100644
index 0000000..00db9c0
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Awaiter.cs
@@ -0,0 +1,79 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if HAS_AWAIT
+using System.Threading;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ /// <summary>
+ /// Gets an awaiter that returns the last value of the observable sequence or throws an exception if the sequence is empty.
+ /// This operation subscribes to the observable sequence, making it hot.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to await.</param>
+ /// <returns>Object that can be awaited.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static AsyncSubject<TSource> GetAwaiter<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.GetAwaiter<TSource>(source);
+ }
+
+ /// <summary>
+ /// Gets an awaiter that returns the last value of the observable sequence or throws an exception if the sequence is empty.
+ /// This operation subscribes and connects to the observable sequence, making it hot.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to await.</param>
+ /// <returns>Object that can be awaited.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static AsyncSubject<TSource> GetAwaiter<TSource>(this IConnectableObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.GetAwaiter<TSource>(source);
+ }
+
+ /// <summary>
+ /// Gets an awaiter that returns the last value of the observable sequence or throws an exception if the sequence is empty.
+ /// This operation subscribes to the observable sequence, making it hot. The supplied CancellationToken can be used to cancel the subscription.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to await.</param>
+ /// <param name="cancellationToken">Cancellation token.</param>
+ /// <returns>Object that can be awaited.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static AsyncSubject<TSource> RunAsync<TSource>(this IObservable<TSource> source, CancellationToken cancellationToken)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.RunAsync<TSource>(source, cancellationToken);
+ }
+
+ /// <summary>
+ /// Gets an awaiter that returns the last value of the observable sequence or throws an exception if the sequence is empty.
+ /// This operation subscribes and connects to the observable sequence, making it hot. The supplied CancellationToken can be used to cancel the subscription and connection.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to await.</param>
+ /// <param name="cancellationToken">Cancellation token.</param>
+ /// <returns>Object that can be awaited.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static AsyncSubject<TSource> RunAsync<TSource>(this IConnectableObservable<TSource> source, CancellationToken cancellationToken)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.RunAsync<TSource>(source, cancellationToken);
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Binding.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Binding.cs
new file mode 100644
index 0000000..3529e97
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Binding.cs
@@ -0,0 +1,610 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Reactive.Concurrency;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region + Multicast +
+
+ /// <summary>
+ /// Multicasts the source sequence notifications through the specified subject to the resulting connectable observable. Upon connection of the
+ /// connectable observable, the subject is subscribed to the source exactly one, and messages are forwarded to the observers registered with
+ /// the connectable observable. For specializations with fixed subject types, see Publish, PublishLast, and Replay.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be pushed into the specified subject.</param>
+ /// <param name="subject">Subject to push source elements into.</param>
+ /// <returns>A connectable observable sequence that upon connection causes the source sequence to push results into the specified subject.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="subject"/> is null.</exception>
+ public static IConnectableObservable<TResult> Multicast<TSource, TResult>(this IObservable<TSource> source, ISubject<TSource, TResult> subject)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (subject == null)
+ throw new ArgumentNullException("subject");
+
+ return s_impl.Multicast<TSource, TResult>(source, subject);
+ }
+
+ /// <summary>
+ /// Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. Each
+ /// subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's
+ /// invocation. For specializations with fixed subject types, see Publish, PublishLast, and Replay.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TIntermediate">The type of the elements produced by the intermediate subject.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence which will be multicasted in the specified selector function.</param>
+ /// <param name="subjectSelector">Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence subject to the policies enforced by the created subject.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="subjectSelector"/> or <paramref name="selector"/> is null.</exception>
+ public static IObservable<TResult> Multicast<TSource, TIntermediate, TResult>(this IObservable<TSource> source, Func<ISubject<TSource, TIntermediate>> subjectSelector, Func<IObservable<TIntermediate>, IObservable<TResult>> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (subjectSelector == null)
+ throw new ArgumentNullException("subjectSelector");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Multicast<TSource, TIntermediate, TResult>(source, subjectSelector, selector);
+ }
+
+ #endregion
+
+ #region + Publish +
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence.
+ /// This operator is a specialization of Multicast using a regular <see cref="System.Reactive.Subjects.Subject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>Subscribers will receive all notifications of the source from the time of the subscription on.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.Subject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> Publish<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Publish<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence.
+ /// This operator is a specialization of Multicast using a regular <see cref="System.Reactive.Subjects.Subject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all notifications of the source from the time of the subscription on.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <seealso cref="System.Reactive.Subjects.Subject&lt;T&gt;"/>
+ public static IObservable<TResult> Publish<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Publish<TSource, TResult>(source, selector);
+ }
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence and starts with initialValue.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.BehaviorSubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="initialValue">Initial value received by observers upon subscription.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>Subscribers will receive immediately receive the initial value, followed by all notifications of the source from the time of the subscription on.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.BehaviorSubject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> Publish<TSource>(this IObservable<TSource> source, TSource initialValue)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Publish<TSource>(source, initialValue);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence and starts with initialValue.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.BehaviorSubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive immediately receive the initial value, followed by all notifications of the source from the time of the subscription on.</param>
+ /// <param name="initialValue">Initial value received by observers upon subscription.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <seealso cref="System.Reactive.Subjects.BehaviorSubject&lt;T&gt;"/>
+ public static IObservable<TResult> Publish<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TSource initialValue)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Publish<TSource, TResult>(source, selector, initialValue);
+ }
+
+ #endregion
+
+ #region + PublishLast +
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence containing only the last notification.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.AsyncSubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>Subscribers will only receive the last notification of the source.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.AsyncSubject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> PublishLast<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.PublishLast<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence containing only the last notification.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.AsyncSubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will only receive the last notification of the source.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <seealso cref="System.Reactive.Subjects.AsyncSubject&lt;T&gt;"/>
+ public static IObservable<TResult> PublishLast<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.PublishLast<TSource, TResult>(source, selector);
+ }
+
+ #endregion
+
+ #region + RefCount +
+
+ /// <summary>
+ /// Returns an observable sequence that stays connected to the source as long as there is at least one subscription to the observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Connectable observable sequence.</param>
+ /// <returns>An observable sequence that stays connected to the source as long as there is at least one subscription to the observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> RefCount<TSource>(this IConnectableObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.RefCount<TSource>(source);
+ }
+
+ #endregion
+
+ #region + Replay +
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying all notifications.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>Subscribers will receive all the notifications of the source.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Replay<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying all notifications.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="scheduler">Scheduler where connected observers will be invoked on.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>Subscribers will receive all the notifications of the source.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Replay<TSource>(source, scheduler);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying all notifications.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Replay<TSource, TResult>(source, selector);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying all notifications.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source.</param>
+ /// <param name="scheduler">Scheduler where connected observers within the selector function will be invoked on.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Replay<TSource, TResult>(source, selector, scheduler);
+ }
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="window">Maximum time length of the replay buffer.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>Subscribers will receive all the notifications of the source subject to the specified replay buffer trimming policy.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, TimeSpan window)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (window < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("window");
+
+ return s_impl.Replay<TSource>(source, window);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.</param>
+ /// <param name="window">Maximum time length of the replay buffer.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TimeSpan window)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (window < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("window");
+
+ return s_impl.Replay<TSource, TResult>(source, selector, window);
+ }
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="window">Maximum time length of the replay buffer.</param>
+ /// <param name="scheduler">Scheduler where connected observers will be invoked on.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>Subscribers will receive all the notifications of the source subject to the specified replay buffer trimming policy.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, TimeSpan window, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (window < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("window");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Replay<TSource>(source, window, scheduler);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.</param>
+ /// <param name="window">Maximum time length of the replay buffer.</param>
+ /// <param name="scheduler">Scheduler where connected observers within the selector function will be invoked on.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TimeSpan window, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (window < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("window");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Replay<TSource, TResult>(source, selector, window, scheduler);
+ }
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying bufferSize notifications.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="bufferSize">Maximum element count of the replay buffer.</param>
+ /// <param name="scheduler">Scheduler where connected observers will be invoked on.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
+ /// <remarks>Subscribers will receive all the notifications of the source subject to the specified replay buffer trimming policy.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, int bufferSize, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (bufferSize < 0)
+ throw new ArgumentOutOfRangeException("bufferSize");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Replay<TSource>(source, bufferSize, scheduler);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum element count for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.</param>
+ /// <param name="bufferSize">Maximum element count of the replay buffer.</param>
+ /// <param name="scheduler">Scheduler where connected observers within the selector function will be invoked on.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (bufferSize < 0)
+ throw new ArgumentOutOfRangeException("bufferSize");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Replay<TSource, TResult>(source, selector, bufferSize, scheduler);
+ }
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum element count for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="bufferSize">Maximum element count of the replay buffer.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
+ /// <remarks>Subscribers will receive all the notifications of the source subject to the specified replay buffer trimming policy.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, int bufferSize)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (bufferSize < 0)
+ throw new ArgumentOutOfRangeException("bufferSize");
+
+ return s_impl.Replay<TSource>(source, bufferSize);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum element count for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.</param>
+ /// <param name="bufferSize">Maximum element count of the replay buffer.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (bufferSize < 0)
+ throw new ArgumentOutOfRangeException("bufferSize");
+
+ return s_impl.Replay<TSource, TResult>(source, selector, bufferSize);
+ }
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length and element count for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="bufferSize">Maximum element count of the replay buffer.</param>
+ /// <param name="window">Maximum time length of the replay buffer.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>Subscribers will receive all the notifications of the source subject to the specified replay buffer trimming policy.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, int bufferSize, TimeSpan window)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (bufferSize < 0)
+ throw new ArgumentOutOfRangeException("bufferSize");
+ if (window < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("window");
+
+ return s_impl.Replay<TSource>(source, bufferSize, window);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length and element count for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.</param>
+ /// <param name="bufferSize">Maximum element count of the replay buffer.</param>
+ /// <param name="window">Maximum time length of the replay buffer.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, TimeSpan window)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (bufferSize < 0)
+ throw new ArgumentOutOfRangeException("bufferSize");
+ if (window < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("window");
+
+ return s_impl.Replay<TSource, TResult>(source, selector, bufferSize, window);
+ }
+
+ /// <summary>
+ /// Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length and element count for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="bufferSize">Maximum element count of the replay buffer.</param>
+ /// <param name="window">Maximum time length of the replay buffer.</param>
+ /// <param name="scheduler">Scheduler where connected observers will be invoked on.</param>
+ /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>Subscribers will receive all the notifications of the source subject to the specified replay buffer trimming policy.</remarks>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, int bufferSize, TimeSpan window, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (bufferSize < 0)
+ throw new ArgumentOutOfRangeException("bufferSize");
+ if (window < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("window");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Replay<TSource>(source, bufferSize, window, scheduler);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length and element count for the replay buffer.
+ /// This operator is a specialization of Multicast using a <see cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
+ /// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.</param>
+ /// <param name="bufferSize">Maximum element count of the replay buffer.</param>
+ /// <param name="window">Maximum time length of the replay buffer.</param>
+ /// <param name="scheduler">Scheduler where connected observers within the selector function will be invoked on.</param>
+ /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
+ /// <seealso cref="System.Reactive.Subjects.ReplaySubject&lt;T&gt;"/>
+ public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, TimeSpan window, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (bufferSize < 0)
+ throw new ArgumentOutOfRangeException("bufferSize");
+ if (window < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("window");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Replay<TSource, TResult>(source, selector, bufferSize, window, scheduler);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs
new file mode 100644
index 0000000..1575b3d
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs
@@ -0,0 +1,503 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region + Chunkify +
+
+ /// <summary>
+ /// Produces an enumerable sequence of consecutive (possibly empty) chunks of the source sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>The enumerable sequence that returns consecutive (possibly empty) chunks upon each iteration.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IEnumerable<IList<TSource>> Chunkify<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Chunkify<TSource>(source);
+ }
+
+ #endregion
+
+ #region + Collect +
+
+ /// <summary>
+ /// Produces an enumerable sequence that returns elements collected/aggregated from the source sequence between consecutive iterations.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements produced by the merge operation during collection.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="newCollector">Factory to create a new collector object.</param>
+ /// <param name="merge">Merges a sequence element with the current collector.</param>
+ /// <returns>The enumerable sequence that returns collected/aggregated elements from the source sequence upon each iteration.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="newCollector"/> or <paramref name="merge"/> is null.</exception>
+ public static IEnumerable<TResult> Collect<TSource, TResult>(this IObservable<TSource> source, Func<TResult> newCollector, Func<TResult, TSource, TResult> merge)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (newCollector == null)
+ throw new ArgumentNullException("newCollector");
+ if (merge == null)
+ throw new ArgumentNullException("merge");
+
+ return s_impl.Collect<TSource, TResult>(source, newCollector, merge);
+ }
+
+ /// <summary>
+ /// Produces an enumerable sequence that returns elements collected/aggregated from the source sequence between consecutive iterations.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements produced by the merge operation during collection.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="getInitialCollector">Factory to create the initial collector object.</param>
+ /// <param name="merge">Merges a sequence element with the current collector.</param>
+ /// <param name="getNewCollector">Factory to replace the current collector by a new collector.</param>
+ /// <returns>The enumerable sequence that returns collected/aggregated elements from the source sequence upon each iteration.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="getInitialCollector"/> or <paramref name="merge"/> or <paramref name="getNewCollector"/> is null.</exception>
+ public static IEnumerable<TResult> Collect<TSource, TResult>(this IObservable<TSource> source, Func<TResult> getInitialCollector, Func<TResult, TSource, TResult> merge, Func<TResult, TResult> getNewCollector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (getInitialCollector == null)
+ throw new ArgumentNullException("getInitialCollector");
+ if (merge == null)
+ throw new ArgumentNullException("merge");
+ if (getNewCollector == null)
+ throw new ArgumentNullException("getNewCollector");
+
+ return s_impl.Collect<TSource, TResult>(source, getInitialCollector, merge, getNewCollector);
+ }
+
+ #endregion
+
+ #region First
+
+ /// <summary>
+ /// Returns the first element of an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>The first element in the observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The source sequence is empty.</exception>
+ /// <seealso cref="Observable.FirstAsync{TSource}(IObservable{TSource})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource First<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.First<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the first element of an observable sequence that satisfies the condition in the predicate.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>The first element in the observable sequence that satisfies the condition in the predicate.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">No element satisfies the condition in the predicate. -or- The source sequence is empty.</exception>
+ /// <seealso cref="Observable.FirstAsync{TSource}(IObservable{TSource}, Func{TSource, bool})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource First<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.First<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region FirstOrDefault
+
+ /// <summary>
+ /// Returns the first element of an observable sequence, or a default value if no such element exists.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>The first element in the observable sequence, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <seealso cref="Observable.FirstOrDefaultAsync{TSource}(IObservable{TSource})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource FirstOrDefault<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.FirstOrDefault<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the first element of an observable sequence that satisfies the condition in the predicate, or a default value if no such element exists.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>The first element in the observable sequence that satisfies the condition in the predicate, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <seealso cref="Observable.FirstOrDefaultAsync{TSource}(IObservable{TSource}, Func{TSource, bool})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource FirstOrDefault<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.FirstOrDefault<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + ForEach +
+
+ /// <summary>
+ /// Invokes an action for each element in the observable sequence, and blocks until the sequence is terminated.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
+ /// <remarks>Because of its blocking nature, this operator is mainly used for testing.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static void ForEach<TSource>(this IObservable<TSource> source, Action<TSource> onNext)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+
+ s_impl.ForEach<TSource>(source, onNext);
+ }
+
+ /// <summary>
+ /// Invokes an action for each element in the observable sequence, incorporating the element's index, and blocks until the sequence is terminated.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
+ /// <remarks>Because of its blocking nature, this operator is mainly used for testing.</remarks>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static void ForEach<TSource>(this IObservable<TSource> source, Action<TSource, int> onNext)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+
+ s_impl.ForEach<TSource>(source, onNext);
+ }
+
+ #endregion
+
+ #region + GetEnumerator +
+
+ /// <summary>
+ /// Returns an enumerator that enumerates all values of the observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to get an enumerator for.</param>
+ /// <returns>The enumerator that can be used to enumerate over the elements in the observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IEnumerator<TSource> GetEnumerator<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.GetEnumerator<TSource>(source);
+ }
+
+ #endregion
+
+ #region Last
+
+ /// <summary>
+ /// Returns the last element of an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>The last element in the observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The source sequence is empty.</exception>
+ /// <seealso cref="Observable.LastAsync{TSource}(IObservable{TSource})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource Last<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Last<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the last element of an observable sequence that satisfies the condition in the predicate.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>The last element in the observable sequence that satisfies the condition in the predicate.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">No element satisfies the condition in the predicate. -or- The source sequence is empty.</exception>
+ /// <seealso cref="Observable.LastAsync{TSource}(IObservable{TSource}, Func{TSource, bool})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource Last<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.Last<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region LastOrDefault
+
+ /// <summary>
+ /// Returns the last element of an observable sequence, or a default value if no such element exists.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>The last element in the observable sequence, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <seealso cref="Observable.LastOrDefaultAsync{TSource}(IObservable{TSource})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource LastOrDefault<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.LastOrDefault<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the last element of an observable sequence that satisfies the condition in the predicate, or a default value if no such element exists.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>The last element in the observable sequence that satisfies the condition in the predicate, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <seealso cref="Observable.LastOrDefaultAsync{TSource}(IObservable{TSource}, Func{TSource, bool})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource LastOrDefault<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.LastOrDefault<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + Latest +
+
+ /// <summary>
+ /// Returns an enumerable sequence whose enumeration returns the latest observed element in the source observable sequence.
+ /// Enumerators on the resulting sequence will never produce the same element repeatedly, and will block until the next element becomes available.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>The enumerable sequence that returns the last sampled element upon each iteration and subsequently blocks until the next element in the observable source sequence becomes available.</returns>
+ public static IEnumerable<TSource> Latest<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Latest<TSource>(source);
+ }
+
+ #endregion
+
+ #region + MostRecent +
+
+ /// <summary>
+ /// Returns an enumerable sequence whose enumeration returns the most recently observed element in the source observable sequence, using the specified initial value in case no element has been sampled yet.
+ /// Enumerators on the resulting sequence never block and can produce the same element repeatedly.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="initialValue">Initial value that will be yielded by the enumerable sequence if no element has been sampled yet.</param>
+ /// <returns>The enumerable sequence that returns the last sampled element upon each iteration.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IEnumerable<TSource> MostRecent<TSource>(this IObservable<TSource> source, TSource initialValue)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.MostRecent<TSource>(source, initialValue);
+ }
+
+ #endregion
+
+ #region + Next +
+
+ /// <summary>
+ /// Returns an enumerable sequence whose enumeration blocks until the next element in the source observable sequence becomes available.
+ /// Enumerators on the resulting sequence will block until the next element becomes available.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>The enumerable sequence that blocks upon each iteration until the next element in the observable source sequence becomes available.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IEnumerable<TSource> Next<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Next<TSource>(source);
+ }
+
+ #endregion
+
+ #region Single
+
+ /// <summary>
+ /// Returns the only element of an observable sequence, and throws an exception if there is not exactly one element in the observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>The single element in the observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The source sequence contains more than one element. -or- The source sequence is empty.</exception>
+ /// <seealso cref="Observable.SingleAsync{TSource}(IObservable{TSource})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource Single<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Single<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the only element of an observable sequence that satisfies the condition in the predicate, and throws an exception if there is not exactly one element matching the predicate in the observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>The single element in the observable sequence that satisfies the condition in the predicate.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">No element satisfies the condition in the predicate. -or- More than one element satisfies the condition in the predicate. -or- The source sequence is empty.</exception>
+ /// <seealso cref="Observable.SingleAsync{TSource}(IObservable{TSource}, Func{TSource, bool})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource Single<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.Single<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region SingleOrDefault
+
+ /// <summary>
+ /// Returns the only element of an observable sequence, or a default value if the observable sequence is empty; this method throws an exception if there is more than one element in the observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>The single element in the observable sequence, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The source sequence contains more than one element.</exception>
+ /// <seealso cref="Observable.SingleOrDefaultAsync{TSource}(IObservable{TSource})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource SingleOrDefault<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.SingleOrDefault<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the only element of an observable sequence that satisfies the condition in the predicate, or a default value if no such element exists; this method throws an exception if there is more than one element matching the predicate in the observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <param name="predicate">A predicate function to evaluate for elements in the source sequence.</param>
+ /// <returns>The single element in the observable sequence that satisfies the condition in the predicate, or a default value if no such element exists.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The sequence contains more than one element that satisfies the condition in the predicate.</exception>
+ /// <seealso cref="Observable.SingleOrDefaultAsync{TSource}(IObservable{TSource}, Func{TSource, bool})"/>
+#if PREFER_ASYNC
+ [Obsolete(Constants_Linq.USE_ASYNC)]
+#endif
+ public static TSource SingleOrDefault<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.SingleOrDefault<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region Wait
+
+ /// <summary>
+ /// Waits for the observable sequence to complete and returns the last element of the sequence.
+ /// If the sequence terminates with an OnError notification, the exception is throw.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source observable sequence.</param>
+ /// <returns>The last element in the observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The source sequence is empty.</exception>
+ public static TSource Wait<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Wait<TSource>(source);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Concurrency.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Concurrency.cs
new file mode 100644
index 0000000..e14df19
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Concurrency.cs
@@ -0,0 +1,155 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Reactive.Concurrency;
+using System.Threading;
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region + ObserveOn +
+
+ /// <summary>
+ /// Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="scheduler">Scheduler to notify observers on.</param>
+ /// <returns>The source sequence whose observations happen on the specified scheduler.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
+ /// that require to be run on a scheduler, use <see cref="Observable.SubscribeOn{TSource}(IObservable{TSource}, IScheduler)"/>.
+ /// </remarks>
+ public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ObserveOn<TSource>(source, scheduler);
+ }
+
+#if !NO_SYNCCTX
+ /// <summary>
+ /// Wraps the source sequence in order to run its observer callbacks on the specified synchronization context.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="context">Synchronization context to notify observers on.</param>
+ /// <returns>The source sequence whose observations happen on the specified synchronization context.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="context"/> is null.</exception>
+ /// <remarks>
+ /// This only invokes observer callbacks on a synchronization context. In case the subscription and/or unsubscription actions have side-effects
+ /// that require to be run on a synchronization context, use <see cref="Observable.SubscribeOn{TSource}(IObservable{TSource}, SynchronizationContext)"/>.
+ /// </remarks>
+ public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, SynchronizationContext context)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (context == null)
+ throw new ArgumentNullException("context");
+
+ return s_impl.ObserveOn<TSource>(source, context);
+ }
+#endif
+
+ #endregion
+
+ #region + SubscribeOn +
+
+ /// <summary>
+ /// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
+ /// see the remarks section for more information on the distinction between SubscribeOn and ObserveOn.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="scheduler">Scheduler to perform subscription and unsubscription actions on.</param>
+ /// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
+ /// callbacks on a scheduler, use <see cref="Observable.ObserveOn{TSource}(IObservable{TSource}, IScheduler)"/>.
+ /// </remarks>
+ public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.SubscribeOn<TSource>(source, scheduler);
+ }
+
+#if !NO_SYNCCTX
+ /// <summary>
+ /// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified synchronization context. This operation is not commonly used;
+ /// see the remarks section for more information on the distinction between SubscribeOn and ObserveOn.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="context">Synchronization context to perform subscription and unsubscription actions on.</param>
+ /// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified synchronization context.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="context"/> is null.</exception>
+ /// <remarks>
+ /// This only performs the side-effects of subscription and unsubscription on the specified synchronization context. In order to invoke observer
+ /// callbacks on a synchronization context, use <see cref="Observable.ObserveOn{TSource}(IObservable{TSource}, SynchronizationContext)"/>.
+ /// </remarks>
+ public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, SynchronizationContext context)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (context == null)
+ throw new ArgumentNullException("context");
+
+ return s_impl.SubscribeOn<TSource>(source, context);
+ }
+#endif
+
+ #endregion
+
+ #region + Synchronize +
+
+ /// <summary>
+ /// Synchronizes the observable sequence such that observer notifications cannot be delivered concurrently.
+ /// This overload is useful to "fix" an observable sequence that exhibits concurrent callbacks on individual observers, which is invalid behavior for the query processor.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <returns>The source sequence whose outgoing calls to observers are synchronized.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>
+ /// It's invalid behavior - according to the observer grammar - for a sequence to exhibit concurrent callbacks on a given observer.
+ /// This operator can be used to "fix" a source that doesn't conform to this rule.
+ /// </remarks>
+ public static IObservable<TSource> Synchronize<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Synchronize<TSource>(source);
+ }
+
+ /// <summary>
+ /// Synchronizes the observable sequence such that observer notifications cannot be delivered concurrently, using the specified gate object.
+ /// This overload is useful when writing n-ary query operators, in order to prevent concurrent callbacks from different sources by synchronizing on a common gate object.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="gate">Gate object to synchronize each observer call on.</param>
+ /// <returns>The source sequence whose outgoing calls to observers are synchronized on the given gate object.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="gate"/> is null.</exception>
+ public static IObservable<TSource> Synchronize<TSource>(this IObservable<TSource> source, object gate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (gate == null)
+ throw new ArgumentNullException("gate");
+
+ return s_impl.Synchronize<TSource>(source, gate);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Conversions.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Conversions.cs
new file mode 100644
index 0000000..d99126f
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Conversions.cs
@@ -0,0 +1,164 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region + Subscribe +
+
+ /// <summary>
+ /// Subscribes an observer to an enumerable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Enumerable sequence to subscribe to.</param>
+ /// <param name="observer">Observer that will receive notifications from the enumerable sequence.</param>
+ /// <returns>Disposable object that can be used to unsubscribe the observer from the enumerable</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="observer"/> is null.</exception>
+ public static IDisposable Subscribe<TSource>(this IEnumerable<TSource> source, IObserver<TSource> observer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (observer == null)
+ throw new ArgumentNullException("observer");
+
+ return s_impl.Subscribe<TSource>(source, observer);
+ }
+
+ /// <summary>
+ /// Subscribes an observer to an enumerable sequence, using the specified scheduler to run the enumeration loop.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Enumerable sequence to subscribe to.</param>
+ /// <param name="observer">Observer that will receive notifications from the enumerable sequence.</param>
+ /// <param name="scheduler">Scheduler to perform the enumeration on.</param>
+ /// <returns>Disposable object that can be used to unsubscribe the observer from the enumerable</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="observer"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IDisposable Subscribe<TSource>(this IEnumerable<TSource> source, IObserver<TSource> observer, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (observer == null)
+ throw new ArgumentNullException("observer");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Subscribe<TSource>(source, observer, scheduler);
+ }
+
+ #endregion
+
+ #region + ToEnumerable +
+
+ /// <summary>
+ /// Converts an observable sequence to an enumerable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to convert to an enumerable sequence.</param>
+ /// <returns>The enumerable sequence containing the elements in the observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IEnumerable<TSource> ToEnumerable<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.ToEnumerable<TSource>(source);
+ }
+
+ #endregion
+
+ #region ToEvent
+
+ /// <summary>
+ /// Exposes an observable sequence as an object with an Action-based .NET event.
+ /// </summary>
+ /// <param name="source">Observable source sequence.</param>
+ /// <returns>The event source object.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IEventSource<Unit> ToEvent(this IObservable<Unit> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.ToEvent(source);
+ }
+
+ /// <summary>
+ /// Exposes an observable sequence as an object with an Action&lt;TSource&gt;-based .NET event.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Observable source sequence.</param>
+ /// <returns>The event source object.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IEventSource<TSource> ToEvent<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.ToEvent<TSource>(source);
+ }
+
+ #endregion
+
+ #region ToEventPattern
+
+ /// <summary>
+ /// Exposes an observable sequence as an object with a .NET event, conforming to the standard .NET event pattern.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="source">Observable source sequence.</param>
+ /// <returns>The event source object.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IEventPatternSource<TEventArgs> ToEventPattern<TEventArgs>(this IObservable<EventPattern<TEventArgs>> source)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.ToEventPattern<TEventArgs>(source);
+ }
+
+ #endregion
+
+ #region + ToObservable +
+
+ /// <summary>
+ /// Converts an enumerable sequence to an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Enumerable sequence to convert to an observable sequence.</param>
+ /// <returns>The observable sequence whose elements are pulled from the given enumerable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> ToObservable<TSource>(this IEnumerable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.ToObservable<TSource>(source);
+ }
+
+ /// <summary>
+ /// Converts an enumerable sequence to an observable sequence, using the specified scheduler to run the enumeration loop.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Enumerable sequence to convert to an observable sequence.</param>
+ /// <param name="scheduler">Scheduler to run the enumeration of the input sequence on.</param>
+ /// <returns>The observable sequence whose elements are pulled from the given enumerable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TSource> ToObservable<TSource>(this IEnumerable<TSource> source, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.ToObservable<TSource>(source, scheduler);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Creation.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Creation.cs
new file mode 100644
index 0000000..3de4a43
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Creation.cs
@@ -0,0 +1,624 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Threading;
+
+#if !NO_TPL
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region - Create -
+
+ /// <summary>
+ /// Creates an observable sequence from a specified Subscribe method implementation.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="subscribe">Implementation of the resulting observable sequence's Subscribe method.</param>
+ /// <returns>The observable sequence with the specified implementation for the Subscribe method.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="subscribe"/> is null.</exception>
+ /// <remarks>
+ /// Use of this operator is preferred over manual implementation of the IObservable&lt;T&gt; interface. In case
+ /// you need a type implementing IObservable&lt;T&gt; rather than an anonymous implementation, consider using
+ /// the <see cref="System.Reactive.ObservableBase&lt;T&gt;"/> abstract base class.
+ /// </remarks>
+ public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, IDisposable> subscribe)
+ {
+ if (subscribe == null)
+ throw new ArgumentNullException("subscribe");
+
+ return s_impl.Create<TResult>(subscribe);
+ }
+
+ /// <summary>
+ /// Creates an observable sequence from a specified Subscribe method implementation.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="subscribe">Implementation of the resulting observable sequence's Subscribe method, returning an Action delegate that will be wrapped in an IDisposable.</param>
+ /// <returns>The observable sequence with the specified implementation for the Subscribe method.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="subscribe"/> is null.</exception>
+ /// <remarks>
+ /// Use of this operator is preferred over manual implementation of the IObservable&lt;T&gt; interface. In case
+ /// you need a type implementing IObservable&lt;T&gt; rather than an anonymous implementation, consider using
+ /// the <see cref="System.Reactive.ObservableBase&lt;T&gt;"/> abstract base class.
+ /// </remarks>
+ public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Action> subscribe)
+ {
+ if (subscribe == null)
+ throw new ArgumentNullException("subscribe");
+
+ return s_impl.Create<TResult>(subscribe);
+ }
+
+ #endregion
+
+ #region - CreateAsync -
+
+#if !NO_TPL
+ /// <summary>
+ /// Creates an observable sequence from a specified cancellable asynchronous Subscribe method.
+ /// The CancellationToken passed to the asynchronous Subscribe method is tied to the returned disposable subscription, allowing best-effort cancellation.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="subscribeAsync">Asynchronous method used to produce elements.</param>
+ /// <returns>The observable sequence surfacing the elements produced by the asynchronous method.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="subscribeAsync"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ /// <remarks>When a subscription to the resulting sequence is disposed, the CancellationToken that was fed to the asynchronous subscribe function will be signaled.</remarks>
+ public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task> subscribeAsync)
+ {
+ if (subscribeAsync == null)
+ throw new ArgumentNullException("subscribeAsync");
+
+ return s_impl.Create<TResult>(subscribeAsync);
+ }
+
+ /// <summary>
+ /// Creates an observable sequence from a specified asynchronous Subscribe method.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="subscribeAsync">Asynchronous method used to produce elements.</param>
+ /// <returns>The observable sequence surfacing the elements produced by the asynchronous method.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="subscribeAsync"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task> subscribeAsync)
+ {
+ if (subscribeAsync == null)
+ throw new ArgumentNullException("subscribeAsync");
+
+ return s_impl.Create<TResult>(subscribeAsync);
+ }
+
+ /// <summary>
+ /// Creates an observable sequence from a specified cancellable asynchronous Subscribe method.
+ /// The CancellationToken passed to the asynchronous Subscribe method is tied to the returned disposable subscription, allowing best-effort cancellation.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="subscribeAsync">Asynchronous method used to implemented the resulting sequence's Subscribe method.</param>
+ /// <returns>The observable sequence with the specified implementation for the Subscribe method.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="subscribeAsync"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ /// <remarks>When a subscription to the resulting sequence is disposed, the CancellationToken that was fed to the asynchronous subscribe function will be signaled.</remarks>
+ public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task<IDisposable>> subscribeAsync)
+ {
+ if (subscribeAsync == null)
+ throw new ArgumentNullException("subscribeAsync");
+
+ return s_impl.Create<TResult>(subscribeAsync);
+ }
+
+ /// <summary>
+ /// Creates an observable sequence from a specified asynchronous Subscribe method.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="subscribeAsync">Asynchronous method used to implemented the resulting sequence's Subscribe method.</param>
+ /// <returns>The observable sequence with the specified implementation for the Subscribe method.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="subscribeAsync"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task<IDisposable>> subscribeAsync)
+ {
+ if (subscribeAsync == null)
+ throw new ArgumentNullException("subscribeAsync");
+
+ return s_impl.Create<TResult>(subscribeAsync);
+ }
+
+ /// <summary>
+ /// Creates an observable sequence from a specified cancellable asynchronous Subscribe method.
+ /// The CancellationToken passed to the asynchronous Subscribe method is tied to the returned disposable subscription, allowing best-effort cancellation.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="subscribeAsync">Asynchronous method used to implemented the resulting sequence's Subscribe method, returning an Action delegate that will be wrapped in an IDisposable.</param>
+ /// <returns>The observable sequence with the specified implementation for the Subscribe method.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="subscribeAsync"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ /// <remarks>When a subscription to the resulting sequence is disposed, the CancellationToken that was fed to the asynchronous subscribe function will be signaled.</remarks>
+ public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task<Action>> subscribeAsync)
+ {
+ if (subscribeAsync == null)
+ throw new ArgumentNullException("subscribeAsync");
+
+ return s_impl.Create<TResult>(subscribeAsync);
+ }
+
+ /// <summary>
+ /// Creates an observable sequence from a specified asynchronous Subscribe method.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="subscribeAsync">Asynchronous method used to implemented the resulting sequence's Subscribe method, returning an Action delegate that will be wrapped in an IDisposable.</param>
+ /// <returns>The observable sequence with the specified implementation for the Subscribe method.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="subscribeAsync"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task<Action>> subscribeAsync)
+ {
+ if (subscribeAsync == null)
+ throw new ArgumentNullException("subscribeAsync");
+
+ return s_impl.Create<TResult>(subscribeAsync);
+ }
+#endif
+
+ #endregion
+
+ #region + Defer +
+
+ /// <summary>
+ /// Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the sequence returned by the factory function, and in the resulting sequence.</typeparam>
+ /// <param name="observableFactory">Observable factory function to invoke for each observer that subscribes to the resulting sequence.</param>
+ /// <returns>An observable sequence whose observers trigger an invocation of the given observable factory function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="observableFactory"/> is null.</exception>
+ public static IObservable<TResult> Defer<TResult>(Func<IObservable<TResult>> observableFactory)
+ {
+ if (observableFactory == null)
+ throw new ArgumentNullException("observableFactory");
+
+ return s_impl.Defer<TResult>(observableFactory);
+ }
+
+ #endregion
+
+ #region + DeferAsync +
+
+#if !NO_TPL
+ /// <summary>
+ /// Returns an observable sequence that starts the specified asynchronous factory function whenever a new observer subscribes.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the sequence returned by the factory function, and in the resulting sequence.</typeparam>
+ /// <param name="observableFactoryAsync">Asynchronous factory function to start for each observer that subscribes to the resulting sequence.</param>
+ /// <returns>An observable sequence whose observers trigger the given asynchronous observable factory function to be started.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="observableFactoryAsync"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ public static IObservable<TResult> Defer<TResult>(Func<Task<IObservable<TResult>>> observableFactoryAsync)
+ {
+ if (observableFactoryAsync == null)
+ throw new ArgumentNullException("observableFactoryAsync");
+
+ return s_impl.Defer<TResult>(observableFactoryAsync);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that starts the specified cancellable asynchronous factory function whenever a new observer subscribes.
+ /// The CancellationToken passed to the asynchronous factory function is tied to the returned disposable subscription, allowing best-effort cancellation.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the sequence returned by the factory function, and in the resulting sequence.</typeparam>
+ /// <param name="observableFactoryAsync">Asynchronous factory function to start for each observer that subscribes to the resulting sequence.</param>
+ /// <returns>An observable sequence whose observers trigger the given asynchronous observable factory function to be started.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="observableFactoryAsync"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ /// <remarks>When a subscription to the resulting sequence is disposed, the CancellationToken that was fed to the asynchronous observable factory function will be signaled.</remarks>
+ public static IObservable<TResult> DeferAsync<TResult>(Func<CancellationToken, Task<IObservable<TResult>>> observableFactoryAsync)
+ {
+ if (observableFactoryAsync == null)
+ throw new ArgumentNullException("observableFactoryAsync");
+
+ return s_impl.Defer<TResult>(observableFactoryAsync);
+ }
+#endif
+
+ #endregion
+
+ #region + Empty +
+
+ /// <summary>
+ /// Returns an empty observable sequence.
+ /// </summary>
+ /// <typeparam name="TResult">The type used for the IObservable&lt;T&gt; type parameter of the resulting sequence.</typeparam>
+ /// <returns>An observable sequence with no elements.</returns>
+ public static IObservable<TResult> Empty<TResult>()
+ {
+ return s_impl.Empty<TResult>();
+ }
+
+ /// <summary>
+ /// Returns an empty observable sequence.
+ /// </summary>
+ /// <typeparam name="TResult">The type used for the IObservable&lt;T&gt; type parameter of the resulting sequence.</typeparam>
+ /// <param name="witness">Object solely used to infer the type of the <typeparamref name="TResult"/> type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.</param>
+ /// <returns>An observable sequence with no elements.</returns>
+ public static IObservable<TResult> Empty<TResult>(TResult witness)
+ {
+ return s_impl.Empty<TResult>(); // Pure inference - no specialized target method.
+ }
+
+ /// <summary>
+ /// Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
+ /// </summary>
+ /// <typeparam name="TResult">The type used for the IObservable&lt;T&gt; type parameter of the resulting sequence.</typeparam>
+ /// <param name="scheduler">Scheduler to send the termination call on.</param>
+ /// <returns>An observable sequence with no elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Empty<TResult>(IScheduler scheduler)
+ {
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Empty<TResult>(scheduler);
+ }
+
+ /// <summary>
+ /// Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
+ /// </summary>
+ /// <typeparam name="TResult">The type used for the IObservable&lt;T&gt; type parameter of the resulting sequence.</typeparam>
+ /// <param name="scheduler">Scheduler to send the termination call on.</param>
+ /// <param name="witness">Object solely used to infer the type of the <typeparamref name="TResult"/> type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.</param>
+ /// <returns>An observable sequence with no elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Empty<TResult>(IScheduler scheduler, TResult witness)
+ {
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Empty<TResult>(scheduler); // Pure inference - no specialized target method.
+ }
+
+ #endregion
+
+ #region + Generate +
+
+ /// <summary>
+ /// Generates an observable sequence by running a state-driven loop producing the sequence's elements.
+ /// </summary>
+ /// <typeparam name="TState">The type of the state used in the generator loop.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="initialState">Initial state.</param>
+ /// <param name="condition">Condition to terminate generation (upon returning false).</param>
+ /// <param name="iterate">Iteration step function.</param>
+ /// <param name="resultSelector">Selector function for results produced in the sequence.</param>
+ /// <returns>The generated sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="iterate"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector)
+ {
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+ if (iterate == null)
+ throw new ArgumentNullException("iterate");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Generate<TState, TResult>(initialState, condition, iterate, resultSelector);
+ }
+
+ /// <summary>
+ /// Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
+ /// </summary>
+ /// <typeparam name="TState">The type of the state used in the generator loop.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="initialState">Initial state.</param>
+ /// <param name="condition">Condition to terminate generation (upon returning false).</param>
+ /// <param name="iterate">Iteration step function.</param>
+ /// <param name="resultSelector">Selector function for results produced in the sequence.</param>
+ /// <param name="scheduler">Scheduler on which to run the generator loop.</param>
+ /// <returns>The generated sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="iterate"/> or <paramref name="resultSelector"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, IScheduler scheduler)
+ {
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+ if (iterate == null)
+ throw new ArgumentNullException("iterate");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Generate<TState, TResult>(initialState, condition, iterate, resultSelector, scheduler);
+ }
+
+ #endregion
+
+ #region + Never +
+
+ /// <summary>
+ /// Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
+ /// </summary>
+ /// <typeparam name="TResult">The type used for the IObservable&lt;T&gt; type parameter of the resulting sequence.</typeparam>
+ /// <returns>An observable sequence whose observers will never get called.</returns>
+ public static IObservable<TResult> Never<TResult>()
+ {
+ return s_impl.Never<TResult>();
+ }
+
+ /// <summary>
+ /// Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
+ /// </summary>
+ /// <typeparam name="TResult">The type used for the IObservable&lt;T&gt; type parameter of the resulting sequence.</typeparam>
+ /// <param name="witness">Object solely used to infer the type of the <typeparamref name="TResult"/> type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.</param>
+ /// <returns>An observable sequence whose observers will never get called.</returns>
+ public static IObservable<TResult> Never<TResult>(TResult witness)
+ {
+ return s_impl.Never<TResult>(); // Pure inference - no specialized target method.
+ }
+
+ #endregion
+
+ #region + Range +
+
+ /// <summary>
+ /// Generates an observable sequence of integral numbers within a specified range.
+ /// </summary>
+ /// <param name="start">The value of the first integer in the sequence.</param>
+ /// <param name="count">The number of sequential integers to generate.</param>
+ /// <returns>An observable sequence that contains a range of sequential integral numbers.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero. -or- <paramref name="start"/> + <paramref name="count"/> - 1 is larger than <see cref="M:System.Int32.MaxValue"/>.</exception>
+ public static IObservable<int> Range(int start, int count)
+ {
+ var max = ((long)start) + count - 1;
+ if (count < 0 || max > int.MaxValue)
+ throw new ArgumentOutOfRangeException("count");
+
+ return s_impl.Range(start, count);
+ }
+
+ /// <summary>
+ /// Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
+ /// </summary>
+ /// <param name="start">The value of the first integer in the sequence.</param>
+ /// <param name="count">The number of sequential integers to generate.</param>
+ /// <param name="scheduler">Scheduler to run the generator loop on.</param>
+ /// <returns>An observable sequence that contains a range of sequential integral numbers.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero. -or- <paramref name="start"/> + <paramref name="count"/> - 1 is larger than <see cref="M:System.Int32.MaxValue"/>.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ public static IObservable<int> Range(int start, int count, IScheduler scheduler)
+ {
+ var max = ((long)start) + count - 1;
+ if (count < 0 || max > int.MaxValue)
+ throw new ArgumentOutOfRangeException("count");
+
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Range(start, count, scheduler);
+ }
+
+ #endregion
+
+ #region + Repeat +
+
+ /// <summary>
+ /// Generates an observable sequence that repeats the given element infinitely.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the element that will be repeated in the produced sequence.</typeparam>
+ /// <param name="value">Element to repeat.</param>
+ /// <returns>An observable sequence that repeats the given element infinitely.</returns>
+ public static IObservable<TResult> Repeat<TResult>(TResult value)
+ {
+ return s_impl.Repeat<TResult>(value);
+ }
+
+ /// <summary>
+ /// Generates an observable sequence that repeats the given element infinitely, using the specified scheduler to send out observer messages.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the element that will be repeated in the produced sequence.</typeparam>
+ /// <param name="value">Element to repeat.</param>
+ /// <param name="scheduler">Scheduler to run the producer loop on.</param>
+ /// <returns>An observable sequence that repeats the given element infinitely.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Repeat<TResult>(TResult value, IScheduler scheduler)
+ {
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Repeat<TResult>(value, scheduler);
+ }
+
+ /// <summary>
+ /// Generates an observable sequence that repeats the given element the specified number of times.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the element that will be repeated in the produced sequence.</typeparam>
+ /// <param name="value">Element to repeat.</param>
+ /// <param name="repeatCount">Number of times to repeat the element.</param>
+ /// <returns>An observable sequence that repeats the given element the specified number of times.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="repeatCount"/> is less than zero.</exception>
+ public static IObservable<TResult> Repeat<TResult>(TResult value, int repeatCount)
+ {
+ if (repeatCount < 0)
+ throw new ArgumentOutOfRangeException("repeatCount");
+
+ return s_impl.Repeat<TResult>(value, repeatCount);
+ }
+
+ /// <summary>
+ /// Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the element that will be repeated in the produced sequence.</typeparam>
+ /// <param name="value">Element to repeat.</param>
+ /// <param name="repeatCount">Number of times to repeat the element.</param>
+ /// <param name="scheduler">Scheduler to run the producer loop on.</param>
+ /// <returns>An observable sequence that repeats the given element the specified number of times.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="repeatCount"/> is less than zero.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Repeat<TResult>(TResult value, int repeatCount, IScheduler scheduler)
+ {
+ if (repeatCount < 0)
+ throw new ArgumentOutOfRangeException("repeatCount");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Repeat<TResult>(value, repeatCount, scheduler);
+ }
+
+ #endregion
+
+ #region + Return +
+
+ /// <summary>
+ /// Returns an observable sequence that contains a single element.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the element that will be returned in the produced sequence.</typeparam>
+ /// <param name="value">Single element in the resulting observable sequence.</param>
+ /// <returns>An observable sequence containing the single specified element.</returns>
+ public static IObservable<TResult> Return<TResult>(TResult value)
+ {
+ return s_impl.Return<TResult>(value);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the element that will be returned in the produced sequence.</typeparam>
+ /// <param name="value">Single element in the resulting observable sequence.</param>
+ /// <param name="scheduler">Scheduler to send the single element on.</param>
+ /// <returns>An observable sequence containing the single specified element.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Return<TResult>(TResult value, IScheduler scheduler)
+ {
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Return<TResult>(value, scheduler);
+ }
+
+ #endregion
+
+ #region + Throw +
+
+ /// <summary>
+ /// Returns an observable sequence that terminates with an exception.
+ /// </summary>
+ /// <typeparam name="TResult">The type used for the IObservable&lt;T&gt; type parameter of the resulting sequence.</typeparam>
+ /// <param name="exception">Exception object used for the sequence's termination.</param>
+ /// <returns>The observable sequence that terminates exceptionally with the specified exception object.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="exception"/> is null.</exception>
+ public static IObservable<TResult> Throw<TResult>(Exception exception)
+ {
+ if (exception == null)
+ throw new ArgumentNullException("exception");
+
+ return s_impl.Throw<TResult>(exception);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that terminates with an exception.
+ /// </summary>
+ /// <typeparam name="TResult">The type used for the IObservable&lt;T&gt; type parameter of the resulting sequence.</typeparam>
+ /// <param name="exception">Exception object used for the sequence's termination.</param>
+ /// <param name="witness">Object solely used to infer the type of the <typeparamref name="TResult"/> type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.</param>
+ /// <returns>The observable sequence that terminates exceptionally with the specified exception object.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="exception"/> is null.</exception>
+ public static IObservable<TResult> Throw<TResult>(Exception exception, TResult witness)
+ {
+ if (exception == null)
+ throw new ArgumentNullException("exception");
+
+ return s_impl.Throw<TResult>(exception); // Pure inference - no specialized target method.
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that terminates with an exception, using the specified scheduler to send out the single OnError message.
+ /// </summary>
+ /// <typeparam name="TResult">The type used for the IObservable&lt;T&gt; type parameter of the resulting sequence.</typeparam>
+ /// <param name="exception">Exception object used for the sequence's termination.</param>
+ /// <param name="scheduler">Scheduler to send the exceptional termination call on.</param>
+ /// <returns>The observable sequence that terminates exceptionally with the specified exception object.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="exception"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Throw<TResult>(Exception exception, IScheduler scheduler)
+ {
+ if (exception == null)
+ throw new ArgumentNullException("exception");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Throw<TResult>(exception, scheduler);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that terminates with an exception, using the specified scheduler to send out the single OnError message.
+ /// </summary>
+ /// <typeparam name="TResult">The type used for the IObservable&lt;T&gt; type parameter of the resulting sequence.</typeparam>
+ /// <param name="exception">Exception object used for the sequence's termination.</param>
+ /// <param name="scheduler">Scheduler to send the exceptional termination call on.</param>
+ /// <param name="witness">Object solely used to infer the type of the <typeparamref name="TResult"/> type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.</param>
+ /// <returns>The observable sequence that terminates exceptionally with the specified exception object.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="exception"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Throw<TResult>(Exception exception, IScheduler scheduler, TResult witness)
+ {
+ if (exception == null)
+ throw new ArgumentNullException("exception");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Throw<TResult>(exception, scheduler); // Pure inference - no specialized target method.
+ }
+
+ #endregion
+
+ #region + Using +
+
+ /// <summary>
+ /// Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <typeparam name="TResource">The type of the resource used during the generation of the resulting sequence. Needs to implement <see cref="System.IDisposable"/>.</typeparam>
+ /// <param name="resourceFactory">Factory function to obtain a resource object.</param>
+ /// <param name="observableFactory">Factory function to obtain an observable sequence that depends on the obtained resource.</param>
+ /// <returns>An observable sequence whose lifetime controls the lifetime of the dependent resource object.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="resourceFactory"/> or <paramref name="observableFactory"/> is null.</exception>
+ public static IObservable<TResult> Using<TResult, TResource>(Func<TResource> resourceFactory, Func<TResource, IObservable<TResult>> observableFactory) where TResource : IDisposable
+ {
+ if (resourceFactory == null)
+ throw new ArgumentNullException("resourceFactory");
+ if (observableFactory == null)
+ throw new ArgumentNullException("observableFactory");
+
+ return s_impl.Using<TResult, TResource>(resourceFactory, observableFactory);
+ }
+
+ #endregion
+
+ #region - UsingAsync -
+
+#if !NO_TPL
+
+ /// <summary>
+ /// Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime. The resource is obtained and used through asynchronous methods.
+ /// The CancellationToken passed to the asynchronous methods is tied to the returned disposable subscription, allowing best-effort cancellation at any stage of the resource acquisition or usage.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <typeparam name="TResource">The type of the resource used during the generation of the resulting sequence. Needs to implement <see cref="System.IDisposable"/>.</typeparam>
+ /// <param name="resourceFactoryAsync">Asynchronous factory function to obtain a resource object.</param>
+ /// <param name="observableFactoryAsync">Asynchronous factory function to obtain an observable sequence that depends on the obtained resource.</param>
+ /// <returns>An observable sequence whose lifetime controls the lifetime of the dependent resource object.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="resourceFactoryAsync"/> or <paramref name="observableFactoryAsync"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ /// <remarks>When a subscription to the resulting sequence is disposed, the CancellationToken that was fed to the asynchronous resource factory and observable factory functions will be signaled.</remarks>
+ public static IObservable<TResult> Using<TResult, TResource>(Func<CancellationToken, Task<TResource>> resourceFactoryAsync, Func<TResource, CancellationToken, Task<IObservable<TResult>>> observableFactoryAsync) where TResource : IDisposable
+ {
+ if (resourceFactoryAsync == null)
+ throw new ArgumentNullException("resourceFactoryAsync");
+ if (observableFactoryAsync == null)
+ throw new ArgumentNullException("observableFactoryAsync");
+
+ return s_impl.Using<TResult, TResource>(resourceFactoryAsync, observableFactoryAsync);
+ }
+
+#endif
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Events.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Events.cs
new file mode 100644
index 0000000..9bb3026
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Events.cs
@@ -0,0 +1,1403 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Reactive.Concurrency;
+using System.Threading;
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region + FromEventPattern +
+
+ #region Strongly typed
+
+ #region Action<EventHandler>
+
+ /// <summary>
+ /// Converts a .NET event, conforming to the standard .NET event pattern based on <see cref="EventHandler"/>, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+#if !NO_EVENTARGS_CONSTRAINT
+ public static IObservable<EventPattern<EventArgs>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler)
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+
+ return s_impl.FromEventPattern(addHandler, removeHandler);
+ }
+#else
+ public static IObservable<EventPattern<object>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler)
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+
+ return s_impl.FromEventPattern(addHandler, removeHandler);
+ }
+#endif
+
+ /// <summary>
+ /// Converts a .NET event, conforming to the standard .NET event pattern based on <see cref="EventHandler"/>, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+#if !NO_EVENTARGS_CONSTRAINT
+ public static IObservable<EventPattern<EventArgs>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IScheduler scheduler)
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern(addHandler, removeHandler, scheduler);
+ }
+#else
+ public static IObservable<EventPattern<object>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IScheduler scheduler)
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern(addHandler, removeHandler, scheduler);
+ }
+#endif
+
+ #endregion
+
+ #region Action<TDelegate>
+
+ /// <summary>
+ /// Converts a .NET event, conforming to the standard .NET event pattern based on a supplied event delegate type, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+
+ return s_impl.FromEventPattern<TDelegate, TEventArgs>(addHandler, removeHandler);
+ }
+
+ /// <summary>
+ /// Converts a .NET event, conforming to the standard .NET event pattern based on a supplied event delegate type, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern<TDelegate, TEventArgs>(addHandler, removeHandler, scheduler);
+ }
+
+ /// <summary>
+ /// Converts a .NET event, conforming to the standard .NET event pattern based on <see cref="EventHandler&lt;TEventArgs&gt;"/>, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="conversion">A function used to convert the given event handler to a delegate compatible with the underlying .NET event. The resulting delegate is used in calls to the addHandler and removeHandler action parameters.</param>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="conversion"/> or <paramref name="addHandler"/> or <paramref name="removeHandler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (conversion == null)
+ throw new ArgumentNullException("conversion");
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+
+ return s_impl.FromEventPattern<TDelegate, TEventArgs>(conversion, addHandler, removeHandler);
+ }
+
+ /// <summary>
+ /// Converts a .NET event, conforming to the standard .NET event pattern based on <see cref="EventHandler&lt;TEventArgs&gt;"/>, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="conversion">A function used to convert the given event handler to a delegate compatible with the underlying .NET event. The resulting delegate is used in calls to the addHandler and removeHandler action parameters.</param>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="conversion"/> or <paramref name="addHandler"/> or <paramref name="removeHandler"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (conversion == null)
+ throw new ArgumentNullException("conversion");
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern<TDelegate, TEventArgs>(conversion, addHandler, removeHandler, scheduler);
+ }
+
+ /// <summary>
+ /// Converts a .NET event, conforming to the standard .NET event pattern based on a supplied event delegate type with a strongly typed sender parameter, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
+ /// <typeparam name="TSender">The type of the sender that raises the event.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+
+ return s_impl.FromEventPattern<TDelegate, TSender, TEventArgs>(addHandler, removeHandler);
+ }
+
+ /// <summary>
+ /// Converts a .NET event, conforming to the standard .NET event pattern based on a supplied event delegate type with a strongly typed sender parameter, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
+ /// <typeparam name="TSender">The type of the sender that raises the event.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern<TDelegate, TSender, TEventArgs>(addHandler, removeHandler, scheduler);
+ }
+
+ #endregion
+
+ #region Action<EventHandler<TEventArgs>>
+
+ /// <summary>
+ /// Converts a .NET event, conforming to the standard .NET event pattern based on <see cref="EventHandler&lt;TEventArgs&gt;"/>, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+
+ return s_impl.FromEventPattern<TEventArgs>(addHandler, removeHandler);
+ }
+
+ /// <summary>
+ /// Converts a .NET event, conforming to the standard .NET event pattern based on <see cref="EventHandler&lt;TEventArgs&gt;"/>, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler, IScheduler scheduler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern<TEventArgs>(addHandler, removeHandler, scheduler);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Reflection
+
+ #region Instance events
+
+ /// <summary>
+ /// Converts an instance .NET event, conforming to the standard .NET event pattern with an <see cref="EventArgs"/> parameter, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the target object type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <param name="target">Object instance that exposes the event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="target"/> or <paramref name="eventName"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+#if !NO_EVENTARGS_CONSTRAINT
+ public static IObservable<EventPattern<EventArgs>> FromEventPattern(object target, string eventName)
+ {
+ if (target == null)
+ throw new ArgumentNullException("target");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+
+ return s_impl.FromEventPattern(target, eventName);
+ }
+#else
+ public static IObservable<EventPattern<object>> FromEventPattern(object target, string eventName)
+ {
+ if (target == null)
+ throw new ArgumentNullException("target");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+
+ return s_impl.FromEventPattern(target, eventName);
+ }
+#endif
+
+ /// <summary>
+ /// Converts an instance .NET event, conforming to the standard .NET event pattern with an <see cref="EventArgs"/> parameter, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the target object type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <param name="target">Object instance that exposes the event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="target"/> or <paramref name="eventName"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+#if !NO_EVENTARGS_CONSTRAINT
+ public static IObservable<EventPattern<EventArgs>> FromEventPattern(object target, string eventName, IScheduler scheduler)
+ {
+ if (target == null)
+ throw new ArgumentNullException("target");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern(target, eventName, scheduler);
+ }
+#else
+ public static IObservable<EventPattern<object>> FromEventPattern(object target, string eventName, IScheduler scheduler)
+ {
+ if (target == null)
+ throw new ArgumentNullException("target");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern(target, eventName, scheduler);
+ }
+#endif
+
+ /// <summary>
+ /// Converts an instance .NET event, conforming to the standard .NET event pattern with strongly typed event arguments, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the target object type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="target">Object instance that exposes the event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="target"/> or <paramref name="eventName"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern. -or- The event's second argument type is not assignable to TEventArgs.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (target == null)
+ throw new ArgumentNullException("target");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+
+ return s_impl.FromEventPattern<TEventArgs>(target, eventName);
+ }
+
+ /// <summary>
+ /// Converts an instance .NET event, conforming to the standard .NET event pattern with strongly typed event arguments, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the target object type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="target">Object instance that exposes the event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="target"/> or <paramref name="eventName"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern. -or- The event's second argument type is not assignable to TEventArgs.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName, IScheduler scheduler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (target == null)
+ throw new ArgumentNullException("target");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern<TEventArgs>(target, eventName, scheduler);
+ }
+
+ /// <summary>
+ /// Converts an instance .NET event, conforming to the standard .NET event pattern with a strongly typed sender and strongly typed event arguments, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the target object type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TSender">The type of the sender that raises the event.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="target">Object instance that exposes the event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="target"/> or <paramref name="eventName"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern. -or- The event's first argument type is not assignable to TSender. -or- The event's second argument type is not assignable to TEventArgs.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (target == null)
+ throw new ArgumentNullException("target");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+
+ return s_impl.FromEventPattern<TSender, TEventArgs>(target, eventName);
+ }
+
+ /// <summary>
+ /// Converts an instance .NET event, conforming to the standard .NET event pattern with a strongly typed sender and strongly typed event arguments, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the target object type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TSender">The type of the sender that raises the event.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="target">Object instance that exposes the event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="target"/> or <paramref name="eventName"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern. -or- The event's first argument type is not assignable to TSender. -or- The event's second argument type is not assignable to TEventArgs.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName, IScheduler scheduler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (target == null)
+ throw new ArgumentNullException("target");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern<TSender, TEventArgs>(target, eventName, scheduler);
+ }
+
+ #endregion
+
+ #region Static events
+
+ /// <summary>
+ /// Converts a static .NET event, conforming to the standard .NET event pattern with an <see cref="EventArgs"/> parameter, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the specified type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <param name="type">Type that exposes the static event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="type"/> or <paramref name="eventName"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+#if !NO_EVENTARGS_CONSTRAINT
+ public static IObservable<EventPattern<EventArgs>> FromEventPattern(Type type, string eventName)
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+
+ return s_impl.FromEventPattern(type, eventName);
+ }
+#else
+ public static IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName)
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+
+ return s_impl.FromEventPattern(type, eventName);
+ }
+#endif
+
+ /// <summary>
+ /// Converts a static .NET event, conforming to the standard .NET event pattern with an <see cref="EventArgs"/> parameter, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the specified type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <param name="type">Type that exposes the static event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="type"/> or <paramref name="eventName"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+#if !NO_EVENTARGS_CONSTRAINT
+ public static IObservable<EventPattern<EventArgs>> FromEventPattern(Type type, string eventName, IScheduler scheduler)
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern(type, eventName, scheduler);
+ }
+#else
+ public static IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName, IScheduler scheduler)
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern(type, eventName, scheduler);
+ }
+#endif
+
+ /// <summary>
+ /// Converts a static .NET event, conforming to the standard .NET event pattern with strongly typed event arguments, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the specified type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="type">Type that exposes the static event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="type"/> or <paramref name="eventName"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern. -or- The event's second argument type is not assignable to TEventArgs.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+
+ return s_impl.FromEventPattern<TEventArgs>(type, eventName);
+ }
+
+ /// <summary>
+ /// Converts a static .NET event, conforming to the standard .NET event pattern with strongly typed event arguments, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the specified type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="type">Type that exposes the static event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="type"/> or <paramref name="eventName"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern. -or- The event's second argument type is not assignable to TEventArgs.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName, IScheduler scheduler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern<TEventArgs>(type, eventName, scheduler);
+ }
+
+ /// <summary>
+ /// Converts a static .NET event, conforming to the standard .NET event pattern with a strongly typed sender and strongly typed event arguments, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the specified type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TSender">The type of the sender that raises the event.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="type">Type that exposes the static event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="type"/> or <paramref name="eventName"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern. -or- The event's first argument type is not assignable to TSender. -or- The event's second argument type is not assignable to TEventArgs.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEventPattern, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+
+ return s_impl.FromEventPattern<TSender, TEventArgs>(type, eventName);
+ }
+
+ /// <summary>
+ /// Converts a static .NET event, conforming to the standard .NET event pattern with a strongly typed sender and strongly typed event arguments, to an observable sequence.
+ /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// Reflection is used to discover the event based on the specified type and the specified event name.
+ /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
+ /// </summary>
+ /// <typeparam name="TSender">The type of the sender that raises the event.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="type">Type that exposes the static event to convert.</param>
+ /// <param name="eventName">Name of the event to convert.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="type"/> or <paramref name="eventName"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">The event could not be found. -or- The event does not conform to the standard .NET event pattern. -or- The event's first argument type is not assignable to TSender. -or- The event's second argument type is not assignable to TEventArgs.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEventPattern calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEventPattern that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEventPattern"/>
+ public static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName, IScheduler scheduler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+ if (eventName == null)
+ throw new ArgumentNullException("eventName");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEventPattern<TSender, TEventArgs>(type, eventName, scheduler);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region + FromEvent +
+
+ #region Action<TDelegate>
+
+ /// <summary>
+ /// Converts a .NET event to an observable sequence, using a conversion function to obtain the event delegate. Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events conforming to the standard .NET event pattern, use any of the FromEventPattern overloads instead.
+ /// </summary>
+ /// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="conversion">A function used to convert the given event handler to a delegate compatible with the underlying .NET event. The resulting delegate is used in calls to the addHandler and removeHandler action parameters.</param>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <returns>The observable sequence that contains the event argument objects passed to the invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="conversion"/> or <paramref name="addHandler"/> or <paramref name="removeHandler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEvent, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEvent, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEvent calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEvent"/>
+ public static IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Func<Action<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
+ {
+ if (conversion == null)
+ throw new ArgumentNullException("conversion");
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+
+ return s_impl.FromEvent<TDelegate, TEventArgs>(conversion, addHandler, removeHandler);
+ }
+
+ /// <summary>
+ /// Converts a .NET event to an observable sequence, using a conversion function to obtain the event delegate. Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events conforming to the standard .NET event pattern, use any of the FromEventPattern overloads instead.
+ /// </summary>
+ /// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="conversion">A function used to convert the given event handler to a delegate compatible with the underlying .NET event. The resulting delegate is used in calls to the addHandler and removeHandler action parameters.</param>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains the event argument objects passed to the invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="conversion"/> or <paramref name="addHandler"/> or <paramref name="removeHandler"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEvent calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEvent that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEvent"/>
+ public static IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Func<Action<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ {
+ if (conversion == null)
+ throw new ArgumentNullException("conversion");
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEvent<TDelegate, TEventArgs>(conversion, addHandler, removeHandler, scheduler);
+ }
+
+ /// <summary>
+ /// Converts a .NET event to an observable sequence, using a supplied event delegate type. Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events conforming to the standard .NET event pattern, use any of the FromEventPattern overloads instead.
+ /// </summary>
+ /// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <returns>The observable sequence that contains the event argument objects passed to the invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEvent, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEvent, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEvent calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEvent"/>
+ public static IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+
+ return s_impl.FromEvent<TDelegate, TEventArgs>(addHandler, removeHandler);
+ }
+
+ /// <summary>
+ /// Converts a .NET event to an observable sequence, using a supplied event delegate type. Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events conforming to the standard .NET event pattern, use any of the FromEventPattern overloads instead.
+ /// </summary>
+ /// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains the event argument objects passed to the invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEvent calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEvent that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEvent"/>
+ public static IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEvent<TDelegate, TEventArgs>(addHandler, removeHandler, scheduler);
+ }
+
+ #endregion
+
+ #region Action<Action<TEventArgs>>
+
+ /// <summary>
+ /// Converts a generic Action-based .NET event to an observable sequence. Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events conforming to the standard .NET event pattern, use any of the FromEventPattern overloads instead.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <returns>The observable sequence that contains the event argument objects passed to the invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEvent, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEvent, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEvent calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEvent"/>
+ public static IObservable<TEventArgs> FromEvent<TEventArgs>(Action<Action<TEventArgs>> addHandler, Action<Action<TEventArgs>> removeHandler)
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+
+ return s_impl.FromEvent<TEventArgs>(addHandler, removeHandler);
+ }
+
+ /// <summary>
+ /// Converts a generic Action-based .NET event to an observable sequence. Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events conforming to the standard .NET event pattern, use any of the FromEventPattern overloads instead.
+ /// </summary>
+ /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains the event argument objects passed to the invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEvent calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEvent that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEvent"/>
+ public static IObservable<TEventArgs> FromEvent<TEventArgs>(Action<Action<TEventArgs>> addHandler, Action<Action<TEventArgs>> removeHandler, IScheduler scheduler)
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEvent<TEventArgs>(addHandler, removeHandler, scheduler);
+ }
+
+ #endregion
+
+ #region Action<Action>
+
+ /// <summary>
+ /// Converts an Action-based .NET event to an observable sequence. Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events conforming to the standard .NET event pattern, use any of the FromEventPattern overloads instead.
+ /// </summary>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <returns>The observable sequence that contains the event argument objects passed to the invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// The current <see cref="SynchronizationContext"/> is captured during the call to FromEvent, and is used to post add and remove handler invocations.
+ /// This behavior ensures add and remove handler operations for thread-affine events are accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// If no SynchronizationContext is present at the point of calling FromEvent, add and remove handler invocations are made synchronously on the thread
+ /// making the Subscribe or Dispose call, respectively.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEvent calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
+ /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
+ /// more concise and easier to understand.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEvent"/>
+ public static IObservable<Unit> FromEvent(Action<Action> addHandler, Action<Action> removeHandler)
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+
+ return s_impl.FromEvent(addHandler, removeHandler);
+ }
+
+ /// <summary>
+ /// Converts an Action-based .NET event to an observable sequence. Each event invocation is surfaced through an OnNext message in the resulting sequence.
+ /// For conversion of events conforming to the standard .NET event pattern, use any of the FromEventPattern overloads instead.
+ /// </summary>
+ /// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
+ /// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
+ /// <param name="scheduler">The scheduler to run the add and remove event handler logic on.</param>
+ /// <returns>The observable sequence that contains the event argument objects passed to the invocations of the underlying .NET event.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// Add and remove handler invocations are made whenever the number of observers grows beyond zero.
+ /// As such, an event handler may be shared by multiple simultaneously active observers, using a subject for multicasting.
+ /// </para>
+ /// <para>
+ /// Add and remove handler invocations are run on the specified scheduler. This behavior allows add and remove handler operations for thread-affine events to be
+ /// accessed from the same context, as required by some UI frameworks.
+ /// </para>
+ /// <para>
+ /// It's recommended to lift FromEvent calls outside event stream query expressions. This best practice reduces clutter of bridging code inside queries,
+ /// making the query expressions more concise and easier to understand. This has additional benefits for overloads of FromEvent that omit the IScheduler
+ /// parameter. For more information, see the remarks section on those overloads.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="Observable.ToEvent"/>
+ public static IObservable<Unit> FromEvent(Action<Action> addHandler, Action<Action> removeHandler, IScheduler scheduler)
+ {
+ if (addHandler == null)
+ throw new ArgumentNullException("addHandler");
+ if (removeHandler == null)
+ throw new ArgumentNullException("removeHandler");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.FromEvent(addHandler, removeHandler, scheduler);
+ }
+
+ #endregion
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Imperative.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Imperative.cs
new file mode 100644
index 0000000..0c8089e
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Imperative.cs
@@ -0,0 +1,299 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Threading;
+
+#if !NO_TPL
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region ForEachAsync
+
+#if !NO_TPL
+ /// <summary>
+ /// Invokes an action for each element in the observable sequence, and returns a Task object that will get signaled when the sequence terminates.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
+ /// <returns>Task that signals the termination of the sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ public static Task ForEachAsync<TSource>(this IObservable<TSource> source, Action<TSource> onNext)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+
+ return s_impl.ForEachAsync<TSource>(source, onNext);
+ }
+
+ /// <summary>
+ /// Invokes an action for each element in the observable sequence, and returns a Task object that will get signaled when the sequence terminates.
+ /// The loop can be quit prematurely by setting the specified cancellation token.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
+ /// <param name="cancellationToken">Cancellation token used to stop the loop.</param>
+ /// <returns>Task that signals the termination of the sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ public static Task ForEachAsync<TSource>(this IObservable<TSource> source, Action<TSource> onNext, CancellationToken cancellationToken)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+
+ return s_impl.ForEachAsync<TSource>(source, onNext, cancellationToken);
+ }
+
+ /// <summary>
+ /// Invokes an action for each element in the observable sequence, incorporating the element's index, and returns a Task object that will get signaled when the sequence terminates.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
+ /// <returns>Task that signals the termination of the sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ public static Task ForEachAsync<TSource>(this IObservable<TSource> source, Action<TSource, int> onNext)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+
+ return s_impl.ForEachAsync<TSource>(source, onNext);
+ }
+
+ /// <summary>
+ /// Invokes an action for each element in the observable sequence, incorporating the element's index, and returns a Task object that will get signaled when the sequence terminates.
+ /// The loop can be quit prematurely by setting the specified cancellation token.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
+ /// <param name="cancellationToken">Cancellation token used to stop the loop.</param>
+ /// <returns>Task that signals the termination of the sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
+ /// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
+ public static Task ForEachAsync<TSource>(this IObservable<TSource> source, Action<TSource, int> onNext, CancellationToken cancellationToken)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+
+ return s_impl.ForEachAsync<TSource>(source, onNext, cancellationToken);
+ }
+#endif
+
+ #endregion
+
+ #region + Case +
+
+ /// <summary>
+ /// Uses <paramref name="selector"/> to determine which source in <paramref name="sources"/> to return, choosing <paramref name="defaultSource"/> if no match is found.
+ /// </summary>
+ /// <typeparam name="TValue">The type of the value returned by the selector function, used to look up the resulting source.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="selector">Selector function invoked to determine the source to lookup in the <paramref name="sources"/> dictionary.</param>
+ /// <param name="sources">Dictionary of sources to select from based on the <paramref name="selector"/> invocation result.</param>
+ /// <param name="defaultSource">Default source to select in case no matching source in <paramref name="sources"/> is found.</param>
+ /// <returns>The observable sequence retrieved from the <paramref name="sources"/> dictionary based on the <paramref name="selector"/> invocation result, or <paramref name="defaultSource"/> if no match is found.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="selector"/> or <paramref name="sources"/> or <paramref name="defaultSource"/> is null.</exception>
+ public static IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources, IObservable<TResult> defaultSource)
+ {
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+ if (defaultSource == null)
+ throw new ArgumentNullException("defaultSource");
+
+ return s_impl.Case<TValue, TResult>(selector, sources, defaultSource);
+ }
+
+ /// <summary>
+ /// Uses <paramref name="selector"/> to determine which source in <paramref name="sources"/> to return, choosing an empty sequence on the specified scheduler if no match is found.
+ /// </summary>
+ /// <typeparam name="TValue">The type of the value returned by the selector function, used to look up the resulting source.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="selector">Selector function invoked to determine the source to lookup in the <paramref name="sources"/> dictionary.</param>
+ /// <param name="sources">Dictionary of sources to select from based on the <paramref name="selector"/> invocation result.</param>
+ /// <param name="scheduler">Scheduler to generate an empty sequence on in case no matching source in <paramref name="sources"/> is found.</param>
+ /// <returns>The observable sequence retrieved from the <paramref name="sources"/> dictionary based on the <paramref name="selector"/> invocation result, or an empty sequence if no match is found.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="selector"/> or <paramref name="sources"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources, IScheduler scheduler)
+ {
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Case<TValue, TResult>(selector, sources, scheduler);
+ }
+
+ /// <summary>
+ /// Uses <paramref name="selector"/> to determine which source in <paramref name="sources"/> to return, choosing an empty sequence if no match is found.
+ /// </summary>
+ /// <typeparam name="TValue">The type of the value returned by the selector function, used to look up the resulting source.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="selector">Selector function invoked to determine the source to lookup in the <paramref name="sources"/> dictionary.</param>
+ /// <param name="sources">Dictionary of sources to select from based on the <paramref name="selector"/> invocation result.</param>
+ /// <returns>The observable sequence retrieved from the <paramref name="sources"/> dictionary based on the <paramref name="selector"/> invocation result, or an empty sequence if no match is found.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="selector"/> or <paramref name="sources"/> is null.</exception>
+ public static IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources)
+ {
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Case<TValue, TResult>(selector, sources);
+ }
+
+ #endregion
+
+ #region + DoWhile +
+
+ /// <summary>
+ /// Repeats the given <paramref name="source"/> as long as the specified <paramref name="condition"/> holds, where the <paramref name="condition"/> is evaluated after each repeated <paramref name="source"/> completed.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source to repeat as long as the <paramref name="condition"/> function evaluates to true.</param>
+ /// <param name="condition">Condition that will be evaluated upon the completion of an iteration through the <paramref name="source"/>, to determine whether repetition of the source is required.</param>
+ /// <returns>The observable sequence obtained by concatenating the <paramref name="source"/> sequence as long as the <paramref name="condition"/> holds.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="condition"/> is null.</exception>
+ public static IObservable<TSource> DoWhile<TSource>(this IObservable<TSource> source, Func<bool> condition)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+
+ return s_impl.DoWhile<TSource>(source, condition);
+ }
+
+ #endregion
+
+ #region + For +
+
+ /// <summary>
+ /// Concatenates the observable sequences obtained by running the <paramref name="resultSelector"/> for each element in the given enumerable <paramref name="source"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the enumerable source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the observable result sequence.</typeparam>
+ /// <param name="source">Enumerable source for which each element will be mapped onto an observable source that will be concatenated in the result sequence.</param>
+ /// <param name="resultSelector">Function to select an observable source for each element in the <paramref name="source"/>.</param>
+ /// <returns>The observable sequence obtained by concatenating the sources returned by <paramref name="resultSelector"/> for each element in the <paramref name="source"/>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> For<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IObservable<TResult>> resultSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.For<TSource, TResult>(source, resultSelector);
+ }
+
+ #endregion
+
+ #region + If +
+
+ /// <summary>
+ /// If the specified <paramref name="condition"/> evaluates true, select the <paramref name="thenSource"/> sequence. Otherwise, select the <paramref name="elseSource"/> sequence.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="condition">Condition evaluated to decide which sequence to return.</param>
+ /// <param name="thenSource">Sequence returned in case <paramref name="condition"/> evaluates true.</param>
+ /// <param name="elseSource">Sequence returned in case <paramref name="condition"/> evaluates false.</param>
+ /// <returns><paramref name="thenSource"/> if <paramref name="condition"/> evaluates true; <paramref name="elseSource"/> otherwise.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="thenSource"/> or <paramref name="elseSource"/> is null.</exception>
+ public static IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource, IObservable<TResult> elseSource)
+ {
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+ if (thenSource == null)
+ throw new ArgumentNullException("thenSource");
+ if (elseSource == null)
+ throw new ArgumentNullException("elseSource");
+
+ return s_impl.If<TResult>(condition, thenSource, elseSource);
+ }
+
+ /// <summary>
+ /// If the specified <paramref name="condition"/> evaluates true, select the <paramref name="thenSource"/> sequence. Otherwise, return an empty sequence.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="condition">Condition evaluated to decide which sequence to return.</param>
+ /// <param name="thenSource">Sequence returned in case <paramref name="condition"/> evaluates true.</param>
+ /// <returns><paramref name="thenSource"/> if <paramref name="condition"/> evaluates true; an empty sequence otherwise.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="thenSource"/> is null.</exception>
+ public static IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource)
+ {
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+ if (thenSource == null)
+ throw new ArgumentNullException("thenSource");
+
+ return s_impl.If<TResult>(condition, thenSource);
+ }
+
+ /// <summary>
+ /// If the specified <paramref name="condition"/> evaluates true, select the <paramref name="thenSource"/> sequence. Otherwise, return an empty sequence generated on the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
+ /// <param name="condition">Condition evaluated to decide which sequence to return.</param>
+ /// <param name="thenSource">Sequence returned in case <paramref name="condition"/> evaluates true.</param>
+ /// <param name="scheduler">Scheduler to generate an empty sequence on in case <paramref name="condition"/> evaluates false.</param>
+ /// <returns><paramref name="thenSource"/> if <paramref name="condition"/> evaluates true; an empty sequence otherwise.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="thenSource"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource, IScheduler scheduler)
+ {
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+ if (thenSource == null)
+ throw new ArgumentNullException("thenSource");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.If<TResult>(condition, thenSource, scheduler);
+ }
+
+ #endregion
+
+ #region + While +
+
+ /// <summary>
+ /// Repeats the given <paramref name="source"/> as long as the specified <paramref name="condition"/> holds, where the <paramref name="condition"/> is evaluated before each repeated <paramref name="source"/> is subscribed to.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source to repeat as long as the <paramref name="condition"/> function evaluates to true.</param>
+ /// <param name="condition">Condition that will be evaluated before subscription to the <paramref name="source"/>, to determine whether repetition of the source is required.</param>
+ /// <returns>The observable sequence obtained by concatenating the <paramref name="source"/> sequence as long as the <paramref name="condition"/> holds.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> While<TSource>(Func<bool> condition, IObservable<TSource> source)
+ {
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.While<TSource>(condition, source);
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Joins.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Joins.cs
new file mode 100644
index 0000000..68afbb9
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Joins.cs
@@ -0,0 +1,91 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+using System.Reactive.Joins;
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region And
+
+ /// <summary>
+ /// Creates a pattern that matches when both observable sequences have an available element.
+ /// </summary>
+ /// <typeparam name="TLeft">The type of the elements in the left sequence.</typeparam>
+ /// <typeparam name="TRight">The type of the elements in the right sequence.</typeparam>
+ /// <param name="left">Observable sequence to match with the right sequence.</param>
+ /// <param name="right">Observable sequence to match with the left sequence.</param>
+ /// <returns>Pattern object that matches when both observable sequences have an available element.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is null.</exception>
+ public static Pattern<TLeft, TRight> And<TLeft, TRight>(this IObservable<TLeft> left, IObservable<TRight> right)
+ {
+ if (left == null)
+ throw new ArgumentNullException("left");
+ if (right == null)
+ throw new ArgumentNullException("right");
+
+ return s_impl.And<TLeft, TRight>(left, right);
+ }
+
+ #endregion
+
+ #region Then
+
+ /// <summary>
+ /// Matches when the observable sequence has an available element and projects the element by invoking the selector function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source">Observable sequence to apply the selector on.</param>
+ /// <param name="selector">Selector that will be invoked for elements in the source sequence.</param>
+ /// <returns>Plan that produces the projected results, to be fed (with other plans) to the When operator.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ public static Plan<TResult> Then<TSource, TResult>(this IObservable<TSource> source, Func<TSource, TResult> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Then<TSource, TResult>(source, selector);
+ }
+
+ #endregion
+
+ #region When
+
+ /// <summary>
+ /// Joins together the results from several patterns.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, obtained from the specified patterns.</typeparam>
+ /// <param name="plans">A series of plans created by use of the Then operator on patterns.</param>
+ /// <returns>An observable sequence with the results from matching several patterns.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="plans"/> is null.</exception>
+ public static IObservable<TResult> When<TResult>(params Plan<TResult>[] plans)
+ {
+ if (plans == null)
+ throw new ArgumentNullException("plans");
+
+ return s_impl.When<TResult>(plans);
+ }
+
+ /// <summary>
+ /// Joins together the results from several patterns.
+ /// </summary>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, obtained from the specified patterns.</typeparam>
+ /// <param name="plans">A series of plans created by use of the Then operator on patterns.</param>
+ /// <returns>An observable sequence with the results form matching several patterns.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="plans"/> is null.</exception>
+ public static IObservable<TResult> When<TResult>(this IEnumerable<Plan<TResult>> plans)
+ {
+ if (plans == null)
+ throw new ArgumentNullException("plans");
+
+ return s_impl.When<TResult>(plans);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Multiple.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Multiple.cs
new file mode 100644
index 0000000..9cb62de
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Multiple.cs
@@ -0,0 +1,2386 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+
+#if !NO_TPL
+using System.Threading; // Used in XML doc comments
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region + Amb +
+
+ /// <summary>
+ /// Propagates the observable sequence that reacts first.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="first">First observable sequence.</param>
+ /// <param name="second">Second observable sequence.</param>
+ /// <returns>An observable sequence that surfaces either of the given sequences, whichever reacted first.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> is null.</exception>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Amb", Justification = "In honor of McCarthy.")]
+ public static IObservable<TSource> Amb<TSource>(this IObservable<TSource> first, IObservable<TSource> second)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+
+ return s_impl.Amb<TSource>(first, second);
+ }
+
+ /// <summary>
+ /// Propagates the observable sequence that reacts first.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sources competing to react first.</param>
+ /// <returns>An observable sequence that surfaces any of the given sequences, whichever reacted first.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Amb", Justification = "In honor of McCarthy.")]
+ public static IObservable<TSource> Amb<TSource>(params IObservable<TSource>[] sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Amb<TSource>(sources);
+ }
+
+ /// <summary>
+ /// Propagates the observable sequence that reacts first.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sources competing to react first.</param>
+ /// <returns>An observable sequence that surfaces any of the given sequences, whichever reacted first.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Amb", Justification = "In honor of McCarthy.")]
+ public static IObservable<TSource> Amb<TSource>(this IEnumerable<IObservable<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Amb<TSource>(sources);
+ }
+
+ #endregion
+
+ #region Buffer
+
+ /// <summary>
+ /// Projects each element of an observable sequence into consecutive non-overlapping buffers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <typeparam name="TBufferClosing">The type of the elements in the sequences indicating buffer closing events.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="bufferClosingSelector">A function invoked to define the boundaries of the produced buffers. A new buffer is started when the previous one is closed.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="bufferClosingSelector"/> is null.</exception>
+ public static IObservable<IList<TSource>> Buffer<TSource, TBufferClosing>(this IObservable<TSource> source, Func<IObservable<TBufferClosing>> bufferClosingSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (bufferClosingSelector == null)
+ throw new ArgumentNullException("bufferClosingSelector");
+
+ return s_impl.Buffer<TSource, TBufferClosing>(source, bufferClosingSelector);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into zero or more buffers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <typeparam name="TBufferOpening">The type of the elements in the sequence indicating buffer opening events, also passed to the closing selector to obtain a sequence of buffer closing events.</typeparam>
+ /// <typeparam name="TBufferClosing">The type of the elements in the sequences indicating buffer closing events.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="bufferOpenings">Observable sequence whose elements denote the creation of new buffers.</param>
+ /// <param name="bufferClosingSelector">A function invoked to define the closing of each produced buffer.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="bufferOpenings"/> or <paramref name="bufferClosingSelector"/> is null.</exception>
+ public static IObservable<IList<TSource>> Buffer<TSource, TBufferOpening, TBufferClosing>(this IObservable<TSource> source, IObservable<TBufferOpening> bufferOpenings, Func<TBufferOpening, IObservable<TBufferClosing>> bufferClosingSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (bufferOpenings == null)
+ throw new ArgumentNullException("bufferOpenings");
+ if (bufferClosingSelector == null)
+ throw new ArgumentNullException("bufferClosingSelector");
+
+ return s_impl.Buffer<TSource, TBufferOpening, TBufferClosing>(source, bufferOpenings, bufferClosingSelector);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into consecutive non-overlapping buffers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <typeparam name="TBufferBoundary">The type of the elements in the sequences indicating buffer boundary events.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="bufferBoundaries">Sequence of buffer boundary markers. The current buffer is closed and a new buffer is opened upon receiving a boundary marker.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="bufferBoundaries"/> is null.</exception>
+ public static IObservable<IList<TSource>> Buffer<TSource, TBufferBoundary>(this IObservable<TSource> source, IObservable<TBufferBoundary> bufferBoundaries)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (bufferBoundaries == null)
+ throw new ArgumentNullException("bufferBoundaries");
+
+ return s_impl.Buffer<TSource, TBufferBoundary>(source, bufferBoundaries);
+ }
+
+ #endregion
+
+ #region + Catch +
+
+ /// <summary>
+ /// Continues an observable sequence that is terminated by an exception of the specified type with the observable sequence produced by the handler.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence and sequences returned by the exception handler function.</typeparam>
+ /// <typeparam name="TException">The type of the exception to catch and handle. Needs to derive from <see cref="System.Exception"/>.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="handler">Exception handler function, producing another observable sequence.</param>
+ /// <returns>An observable sequence containing the source sequence's elements, followed by the elements produced by the handler's resulting observable sequence in case an exception occurred.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="handler"/> is null.</exception>
+ public static IObservable<TSource> Catch<TSource, TException>(this IObservable<TSource> source, Func<TException, IObservable<TSource>> handler) where TException : Exception
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (handler == null)
+ throw new ArgumentNullException("handler");
+
+ return s_impl.Catch<TSource, TException>(source, handler);
+ }
+
+ /// <summary>
+ /// Continues an observable sequence that is terminated by an exception with the next observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence and handler sequence.</typeparam>
+ /// <param name="first">First observable sequence whose exception (if any) is caught.</param>
+ /// <param name="second">Second observable sequence used to produce results when an error occurred in the first sequence.</param>
+ /// <returns>An observable sequence containing the first sequence's elements, followed by the elements of the second sequence in case an exception occurred.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> is null.</exception>
+ public static IObservable<TSource> Catch<TSource>(this IObservable<TSource> first, IObservable<TSource> second)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+
+ return s_impl.Catch<TSource>(first, second);
+ }
+
+ /// <summary>
+ /// Continues an observable sequence that is terminated by an exception with the next observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source and handler sequences.</typeparam>
+ /// <param name="sources">Observable sequences to catch exceptions for.</param>
+ /// <returns>An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> Catch<TSource>(params IObservable<TSource>[] sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Catch<TSource>(sources);
+ }
+
+ /// <summary>
+ /// Continues an observable sequence that is terminated by an exception with the next observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source and handler sequences.</typeparam>
+ /// <param name="sources">Observable sequences to catch exceptions for.</param>
+ /// <returns>An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> Catch<TSource>(this IEnumerable<IObservable<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Catch<TSource>(sources);
+ }
+
+ #endregion
+
+ #region + CombineLatest +
+
+ /// <summary>
+ /// Merges two observable sequences into one observable sequence by using the selector function whenever one of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="first">First observable source.</param>
+ /// <param name="second">Second observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever either of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of both sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TResult>(this IObservable<TSource1> first, IObservable<TSource2> second, Func<TSource1, TSource2, TResult> resultSelector)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TResult>(first, second, resultSelector);
+ }
+
+#if !NO_PERF
+
+ /* The following code is generated by a tool checked in to $/.../Source/Tools/CodeGenerators. */
+
+ #region CombineLatest auto-generated code (8/3/2012 6:37:08 PM)
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, Func<TSource1, TSource2, TSource3, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TResult>(source1, source2, source3, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, Func<TSource1, TSource2, TSource3, TSource4, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TResult>(source1, source2, source3, source4, resultSelector);
+ }
+
+#if !NO_LARGEARITY
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TResult>(source1, source2, source3, source4, source5, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult>(source1, source2, source3, source4, source5, source6, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult>(source1, source2, source3, source4, source5, source6, source7, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TSource12">The type of the elements in the twelfth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="source12">Twelfth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="source12"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (source12 == null)
+ throw new ArgumentNullException("source12");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TSource12">The type of the elements in the twelfth source sequence.</typeparam>
+ /// <typeparam name="TSource13">The type of the elements in the thirteenth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="source12">Twelfth observable source.</param>
+ /// <param name="source13">Thirteenth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="source12"/> or <paramref name="source13"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (source12 == null)
+ throw new ArgumentNullException("source12");
+ if (source13 == null)
+ throw new ArgumentNullException("source13");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TSource12">The type of the elements in the twelfth source sequence.</typeparam>
+ /// <typeparam name="TSource13">The type of the elements in the thirteenth source sequence.</typeparam>
+ /// <typeparam name="TSource14">The type of the elements in the fourteenth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="source12">Twelfth observable source.</param>
+ /// <param name="source13">Thirteenth observable source.</param>
+ /// <param name="source14">Fourteenth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="source12"/> or <paramref name="source13"/> or <paramref name="source14"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (source12 == null)
+ throw new ArgumentNullException("source12");
+ if (source13 == null)
+ throw new ArgumentNullException("source13");
+ if (source14 == null)
+ throw new ArgumentNullException("source14");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TSource12">The type of the elements in the twelfth source sequence.</typeparam>
+ /// <typeparam name="TSource13">The type of the elements in the thirteenth source sequence.</typeparam>
+ /// <typeparam name="TSource14">The type of the elements in the fourteenth source sequence.</typeparam>
+ /// <typeparam name="TSource15">The type of the elements in the fifteenth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="source12">Twelfth observable source.</param>
+ /// <param name="source13">Thirteenth observable source.</param>
+ /// <param name="source14">Fourteenth observable source.</param>
+ /// <param name="source15">Fifteenth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="source12"/> or <paramref name="source13"/> or <paramref name="source14"/> or <paramref name="source15"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, IObservable<TSource15> source15, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (source12 == null)
+ throw new ArgumentNullException("source12");
+ if (source13 == null)
+ throw new ArgumentNullException("source13");
+ if (source14 == null)
+ throw new ArgumentNullException("source14");
+ if (source15 == null)
+ throw new ArgumentNullException("source15");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TSource12">The type of the elements in the twelfth source sequence.</typeparam>
+ /// <typeparam name="TSource13">The type of the elements in the thirteenth source sequence.</typeparam>
+ /// <typeparam name="TSource14">The type of the elements in the fourteenth source sequence.</typeparam>
+ /// <typeparam name="TSource15">The type of the elements in the fifteenth source sequence.</typeparam>
+ /// <typeparam name="TSource16">The type of the elements in the sixteenth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="source12">Twelfth observable source.</param>
+ /// <param name="source13">Thirteenth observable source.</param>
+ /// <param name="source14">Fourteenth observable source.</param>
+ /// <param name="source15">Fifteenth observable source.</param>
+ /// <param name="source16">Sixteenth observable source.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="source12"/> or <paramref name="source13"/> or <paramref name="source14"/> or <paramref name="source15"/> or <paramref name="source16"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, IObservable<TSource15> source15, IObservable<TSource16> source16, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (source12 == null)
+ throw new ArgumentNullException("source12");
+ if (source13 == null)
+ throw new ArgumentNullException("source13");
+ if (source14 == null)
+ throw new ArgumentNullException("source14");
+ if (source15 == null)
+ throw new ArgumentNullException("source15");
+ if (source16 == null)
+ throw new ArgumentNullException("source16");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, source16, resultSelector);
+ }
+
+#endif
+
+ #endregion
+
+#endif
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="sources">Observable sources.</param>
+ /// <param name="resultSelector">Function to invoke whenever any of the sources produces an element. For efficiency, the input list is reused after the selector returns. Either aggregate or copy the values during the function call.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> CombineLatest<TSource, TResult>(this IEnumerable<IObservable<TSource>> sources, Func<IList<TSource>, TResult> resultSelector)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.CombineLatest<TSource, TResult>(sources, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by emitting a list with the latest source elements whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences, and in the lists in the result sequence.</typeparam>
+ /// <param name="sources">Observable sources.</param>
+ /// <returns>An observable sequence containing lists of the latest elements of the sources.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<IList<TSource>> CombineLatest<TSource>(this IEnumerable<IObservable<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.CombineLatest<TSource>(sources);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by emitting a list with the latest source elements whenever any of the observable sequences produces an element.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences, and in the lists in the result sequence.</typeparam>
+ /// <param name="sources">Observable sources.</param>
+ /// <returns>An observable sequence containing lists of the latest elements of the sources.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<IList<TSource>> CombineLatest<TSource>(params IObservable<TSource>[] sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.CombineLatest<TSource>(sources);
+ }
+
+ #endregion
+
+ #region + Concat +
+
+ /// <summary>
+ /// Concatenates the second observable sequence to the first observable sequence upon successful termination of the first.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="first">First observable sequence.</param>
+ /// <param name="second">Second observable sequence.</param>
+ /// <returns>An observable sequence that contains the elements of the first sequence, followed by those of the second the sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> is null.</exception>
+ public static IObservable<TSource> Concat<TSource>(this IObservable<TSource> first, IObservable<TSource> second)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+
+ return s_impl.Concat<TSource>(first, second);
+ }
+
+ /// <summary>
+ /// Concatenates all of the specified observable sequences, as long as the previous observable sequence terminated successfully.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sequences to concatenate.</param>
+ /// <returns>An observable sequence that contains the elements of each given sequence, in sequential order.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> Concat<TSource>(params IObservable<TSource>[] sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Concat<TSource>(sources);
+ }
+
+ /// <summary>
+ /// Concatenates all observable sequences in the given enumerable sequence, as long as the previous observable sequence terminated successfully.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sequences to concatenate.</param>
+ /// <returns>An observable sequence that contains the elements of each given sequence, in sequential order.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> Concat<TSource>(this IEnumerable<IObservable<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Concat<TSource>(sources);
+ }
+
+ /// <summary>
+ /// Concatenates all inner observable sequences, as long as the previous observable sequence terminated successfully.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sequence of inner observable sequences.</param>
+ /// <returns>An observable sequence that contains the elements of each observed inner sequence, in sequential order.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> Concat<TSource>(this IObservable<IObservable<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Concat<TSource>(sources);
+ }
+
+#if !NO_TPL
+
+ /// <summary>
+ /// Concatenates all task results, as long as the previous task terminated successfully.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the results produced by the tasks.</typeparam>
+ /// <param name="sources">Observable sequence of tasks.</param>
+ /// <returns>An observable sequence that contains the results of each task, in sequential order.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ /// <remarks>If the tasks support cancellation, consider manual conversion of the tasks using <see cref="Observable.FromAsync{TSource}(Func{CancellationToken, Task{TSource}})"/>, followed by a concatenation operation using <see cref="Observable.Concat{TSource}(IObservable{IObservable{TSource}})"/>.</remarks>
+ public static IObservable<TSource> Concat<TSource>(this IObservable<Task<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Concat<TSource>(sources);
+ }
+
+#endif
+
+ #endregion
+
+ #region + Merge +
+
+ /// <summary>
+ /// Merges elements from all inner observable sequences into a single observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sequence of inner observable sequences.</param>
+ /// <returns>The observable sequence that merges the elements of the inner sequences.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> Merge<TSource>(this IObservable<IObservable<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Merge<TSource>(sources);
+ }
+
+#if !NO_TPL
+
+ /// <summary>
+ /// Merges results from all source tasks into a single observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the results produced by the source tasks.</typeparam>
+ /// <param name="sources">Observable sequence of tasks.</param>
+ /// <returns>The observable sequence that merges the results of the source tasks.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ /// <remarks>If the tasks support cancellation, consider manual conversion of the tasks using <see cref="Observable.FromAsync{TSource}(Func{CancellationToken, Task{TSource}})"/>, followed by a merge operation using <see cref="Observable.Merge{TSource}(IObservable{IObservable{TSource}})"/>.</remarks>
+ public static IObservable<TSource> Merge<TSource>(this IObservable<Task<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Merge<TSource>(sources);
+ }
+
+#endif
+
+ /// <summary>
+ /// Merges elements from all inner observable sequences into a single observable sequence, limiting the number of concurrent subscriptions to inner sequences.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sequence of inner observable sequences.</param>
+ /// <param name="maxConcurrent">Maximum number of inner observable sequences being subscribed to concurrently.</param>
+ /// <returns>The observable sequence that merges the elements of the inner sequences.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxConcurrent"/> is less than or equal to zero.</exception>
+ public static IObservable<TSource> Merge<TSource>(this IObservable<IObservable<TSource>> sources, int maxConcurrent)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+ if (maxConcurrent <= 0)
+ throw new ArgumentOutOfRangeException("maxConcurrent");
+
+ return s_impl.Merge<TSource>(sources, maxConcurrent);
+ }
+
+ /// <summary>
+ /// Merges elements from all observable sequences in the given enumerable sequence into a single observable sequence, limiting the number of concurrent subscriptions to inner sequences.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Enumerable sequence of observable sequences.</param>
+ /// <param name="maxConcurrent">Maximum number of observable sequences being subscribed to concurrently.</param>
+ /// <returns>The observable sequence that merges the elements of the observable sequences.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxConcurrent"/> is less than or equal to zero.</exception>
+ public static IObservable<TSource> Merge<TSource>(this IEnumerable<IObservable<TSource>> sources, int maxConcurrent)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+ if (maxConcurrent <= 0)
+ throw new ArgumentOutOfRangeException("maxConcurrent");
+
+ return s_impl.Merge<TSource>(sources, maxConcurrent);
+ }
+
+ /// <summary>
+ /// Merges elements from all observable sequences in the given enumerable sequence into a single observable sequence, limiting the number of concurrent subscriptions to inner sequences, and using the specified scheduler for enumeration of and subscription to the sources.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Enumerable sequence of observable sequences.</param>
+ /// <param name="maxConcurrent">Maximum number of observable sequences being subscribed to concurrently.</param>
+ /// <param name="scheduler">Scheduler to run the enumeration of the sequence of sources on.</param>
+ /// <returns>The observable sequence that merges the elements of the observable sequences.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxConcurrent"/> is less than or equal to zero.</exception>
+ public static IObservable<TSource> Merge<TSource>(this IEnumerable<IObservable<TSource>> sources, int maxConcurrent, IScheduler scheduler)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+ if (maxConcurrent <= 0)
+ throw new ArgumentOutOfRangeException("maxConcurrent");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Merge<TSource>(sources, maxConcurrent, scheduler);
+ }
+
+ /// <summary>
+ /// Merges elements from two observable sequences into a single observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="first">First observable sequence.</param>
+ /// <param name="second">Second observable sequence.</param>
+ /// <returns>The observable sequence that merges the elements of the given sequences.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> is null.</exception>
+ public static IObservable<TSource> Merge<TSource>(this IObservable<TSource> first, IObservable<TSource> second)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+
+ return s_impl.Merge<TSource>(first, second);
+ }
+
+ /// <summary>
+ /// Merges elements from two observable sequences into a single observable sequence, using the specified scheduler for enumeration of and subscription to the sources.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="first">First observable sequence.</param>
+ /// <param name="second">Second observable sequence.</param>
+ /// <param name="scheduler">Scheduler used to introduce concurrency for making subscriptions to the given sequences.</param>
+ /// <returns>The observable sequence that merges the elements of the given sequences.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TSource> Merge<TSource>(this IObservable<TSource> first, IObservable<TSource> second, IScheduler scheduler)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Merge<TSource>(first, second, scheduler);
+ }
+
+ /// <summary>
+ /// Merges elements from all of the specified observable sequences into a single observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sequences.</param>
+ /// <returns>The observable sequence that merges the elements of the observable sequences.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> Merge<TSource>(params IObservable<TSource>[] sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Merge<TSource>(sources);
+ }
+
+ /// <summary>
+ /// Merges elements from all of the specified observable sequences into a single observable sequence, using the specified scheduler for enumeration of and subscription to the sources.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sequences.</param>
+ /// <param name="scheduler">Scheduler to run the enumeration of the sequence of sources on.</param>
+ /// <returns>The observable sequence that merges the elements of the observable sequences.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> Merge<TSource>(IScheduler scheduler, params IObservable<TSource>[] sources)
+ {
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Merge<TSource>(scheduler, sources);
+ }
+
+ /// <summary>
+ /// Merges elements from all observable sequences in the given enumerable sequence into a single observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Enumerable sequence of observable sequences.</param>
+ /// <returns>The observable sequence that merges the elements of the observable sequences.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> Merge<TSource>(this IEnumerable<IObservable<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Merge<TSource>(sources);
+ }
+
+ /// <summary>
+ /// Merges elements from all observable sequences in the given enumerable sequence into a single observable sequence, using the specified scheduler for enumeration of and subscription to the sources.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Enumerable sequence of observable sequences.</param>
+ /// <param name="scheduler">Scheduler to run the enumeration of the sequence of sources on.</param>
+ /// <returns>The observable sequence that merges the elements of the observable sequences.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TSource> Merge<TSource>(this IEnumerable<IObservable<TSource>> sources, IScheduler scheduler)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Merge<TSource>(sources, scheduler);
+ }
+
+ #endregion
+
+ #region + OnErrorResumeNext +
+
+ /// <summary>
+ /// Concatenates the second observable sequence to the first observable sequence upon successful or exceptional termination of the first.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="first">First observable sequence whose exception (if any) is caught.</param>
+ /// <param name="second">Second observable sequence used to produce results after the first sequence terminates.</param>
+ /// <returns>An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> is null.</exception>
+ public static IObservable<TSource> OnErrorResumeNext<TSource>(this IObservable<TSource> first, IObservable<TSource> second)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+
+ return s_impl.OnErrorResumeNext<TSource>(first, second);
+ }
+
+ /// <summary>
+ /// Concatenates all of the specified observable sequences, even if the previous observable sequence terminated exceptionally.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sequences to concatenate.</param>
+ /// <returns>An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> OnErrorResumeNext<TSource>(params IObservable<TSource>[] sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.OnErrorResumeNext<TSource>(sources);
+ }
+
+ /// <summary>
+ /// Concatenates all observable sequences in the given enumerable sequence, even if the previous observable sequence terminated exceptionally.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sequences to concatenate.</param>
+ /// <returns>An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> OnErrorResumeNext<TSource>(this IEnumerable<IObservable<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.OnErrorResumeNext<TSource>(sources);
+ }
+
+ #endregion
+
+ #region + SkipUntil +
+
+ /// <summary>
+ /// Returns the elements from the source observable sequence only after the other observable sequence produces an element.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TOther">The type of the elements in the other sequence that indicates the end of skip behavior.</typeparam>
+ /// <param name="source">Source sequence to propagate elements for.</param>
+ /// <param name="other">Observable sequence that triggers propagation of elements of the source sequence.</param>
+ /// <returns>An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="other"/> is null.</exception>
+ public static IObservable<TSource> SkipUntil<TSource, TOther>(this IObservable<TSource> source, IObservable<TOther> other)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (other == null)
+ throw new ArgumentNullException("other");
+
+ return s_impl.SkipUntil<TSource, TOther>(source, other);
+ }
+
+ #endregion
+
+ #region + Switch +
+
+ /// <summary>
+ /// Switches between the inner observable sequences such that the resulting sequence always produces elements from the most recently received inner observable sequence.
+ /// Each time a new inner observable sequence is received, the previous inner observable sequence is unsubscribed from.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <param name="sources">Observable sequence of inner observable sequences.</param>
+ /// <returns>The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<TSource> Switch<TSource>(this IObservable<IObservable<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Switch<TSource>(sources);
+ }
+
+#if !NO_TPL
+
+ /// <summary>
+ /// Switches between the tasks such that the resulting sequence always produces results from the most recently received task.
+ /// Each time a new task is received, the previous task's result is ignored.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the results produced by the source tasks.</typeparam>
+ /// <param name="sources">Observable sequence of tasks.</param>
+ /// <returns>The observable sequence that at any point in time produces the result of the most recent task that has been received.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ /// <remarks>If the tasks support cancellation, consider manual conversion of the tasks using <see cref="Observable.FromAsync{TSource}(Func{CancellationToken, Task{TSource}})"/>, followed by a switch operation using <see cref="Observable.Switch{TSource}(IObservable{IObservable{TSource}})"/>.</remarks>
+ public static IObservable<TSource> Switch<TSource>(this IObservable<Task<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Switch<TSource>(sources);
+ }
+
+#endif
+
+ #endregion
+
+ #region + TakeUntil +
+
+ /// <summary>
+ /// Returns the elements from the source observable sequence until the other observable sequence produces an element.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TOther">The type of the elements in the other sequence that indicates the end of take behavior.</typeparam>
+ /// <param name="source">Source sequence to propagate elements for.</param>
+ /// <param name="other">Observable sequence that terminates propagation of elements of the source sequence.</param>
+ /// <returns>An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="other"/> is null.</exception>
+ public static IObservable<TSource> TakeUntil<TSource, TOther>(this IObservable<TSource> source, IObservable<TOther> other)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (other == null)
+ throw new ArgumentNullException("other");
+
+ return s_impl.TakeUntil<TSource, TOther>(source, other);
+ }
+
+ #endregion
+
+ #region Window
+
+ /// <summary>
+ /// Projects each element of an observable sequence into consecutive non-overlapping windows.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <typeparam name="TWindowClosing">The type of the elements in the sequences indicating window closing events.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="windowClosingSelector">A function invoked to define the boundaries of the produced windows. A new window is started when the previous one is closed.</param>
+ /// <returns>An observable sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="windowClosingSelector"/> is null.</exception>
+ public static IObservable<IObservable<TSource>> Window<TSource, TWindowClosing>(this IObservable<TSource> source, Func<IObservable<TWindowClosing>> windowClosingSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (windowClosingSelector == null)
+ throw new ArgumentNullException("windowClosingSelector");
+
+ return s_impl.Window<TSource, TWindowClosing>(source, windowClosingSelector);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into zero or more windows.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <typeparam name="TWindowOpening">The type of the elements in the sequence indicating window opening events, also passed to the closing selector to obtain a sequence of window closing events.</typeparam>
+ /// <typeparam name="TWindowClosing">The type of the elements in the sequences indicating window closing events.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="windowOpenings">Observable sequence whose elements denote the creation of new windows.</param>
+ /// <param name="windowClosingSelector">A function invoked to define the closing of each produced window.</param>
+ /// <returns>An observable sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="windowOpenings"/> or <paramref name="windowClosingSelector"/> is null.</exception>
+ public static IObservable<IObservable<TSource>> Window<TSource, TWindowOpening, TWindowClosing>(this IObservable<TSource> source, IObservable<TWindowOpening> windowOpenings, Func<TWindowOpening, IObservable<TWindowClosing>> windowClosingSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (windowOpenings == null)
+ throw new ArgumentNullException("windowOpenings");
+ if (windowClosingSelector == null)
+ throw new ArgumentNullException("windowClosingSelector");
+
+ return s_impl.Window<TSource, TWindowOpening, TWindowClosing>(source, windowOpenings, windowClosingSelector);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into consecutive non-overlapping windows.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <typeparam name="TWindowBoundary">The type of the elements in the sequences indicating window boundary events.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="windowBoundaries">Sequence of window boundary markers. The current window is closed and a new window is opened upon receiving a boundary marker.</param>
+ /// <returns>An observable sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="windowBoundaries"/> is null.</exception>
+ public static IObservable<IObservable<TSource>> Window<TSource, TWindowBoundary>(this IObservable<TSource> source, IObservable<TWindowBoundary> windowBoundaries)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (windowBoundaries == null)
+ throw new ArgumentNullException("windowBoundaries");
+
+ return s_impl.Window<TSource, TWindowBoundary>(source, windowBoundaries);
+ }
+
+ #endregion
+
+ #region + Zip +
+
+ /// <summary>
+ /// Merges two observable sequences into one observable sequence by combining their elements in a pairwise fashion.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="first">First observable source.</param>
+ /// <param name="second">Second observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each consecutive pair of elements from the first and second source.</param>
+ /// <returns>An observable sequence containing the result of pairwise combining the elements of the first and second source using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TResult>(this IObservable<TSource1> first, IObservable<TSource2> second, Func<TSource1, TSource2, TResult> resultSelector)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TResult>(first, second, resultSelector);
+ }
+
+#if !NO_PERF
+
+ /* The following code is generated by a tool checked in to $/.../Source/Tools/CodeGenerators. */
+
+ #region Zip auto-generated code (8/3/2012 6:37:02 PM)
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, Func<TSource1, TSource2, TSource3, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TResult>(source1, source2, source3, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, Func<TSource1, TSource2, TSource3, TSource4, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TResult>(source1, source2, source3, source4, resultSelector);
+ }
+
+#if !NO_LARGEARITY
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TResult>(source1, source2, source3, source4, source5, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult>(source1, source2, source3, source4, source5, source6, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult>(source1, source2, source3, source4, source5, source6, source7, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TSource12">The type of the elements in the twelfth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="source12">Twelfth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="source12"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (source12 == null)
+ throw new ArgumentNullException("source12");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TSource12">The type of the elements in the twelfth source sequence.</typeparam>
+ /// <typeparam name="TSource13">The type of the elements in the thirteenth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="source12">Twelfth observable source.</param>
+ /// <param name="source13">Thirteenth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="source12"/> or <paramref name="source13"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (source12 == null)
+ throw new ArgumentNullException("source12");
+ if (source13 == null)
+ throw new ArgumentNullException("source13");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TSource12">The type of the elements in the twelfth source sequence.</typeparam>
+ /// <typeparam name="TSource13">The type of the elements in the thirteenth source sequence.</typeparam>
+ /// <typeparam name="TSource14">The type of the elements in the fourteenth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="source12">Twelfth observable source.</param>
+ /// <param name="source13">Thirteenth observable source.</param>
+ /// <param name="source14">Fourteenth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="source12"/> or <paramref name="source13"/> or <paramref name="source14"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (source12 == null)
+ throw new ArgumentNullException("source12");
+ if (source13 == null)
+ throw new ArgumentNullException("source13");
+ if (source14 == null)
+ throw new ArgumentNullException("source14");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TSource12">The type of the elements in the twelfth source sequence.</typeparam>
+ /// <typeparam name="TSource13">The type of the elements in the thirteenth source sequence.</typeparam>
+ /// <typeparam name="TSource14">The type of the elements in the fourteenth source sequence.</typeparam>
+ /// <typeparam name="TSource15">The type of the elements in the fifteenth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="source12">Twelfth observable source.</param>
+ /// <param name="source13">Thirteenth observable source.</param>
+ /// <param name="source14">Fourteenth observable source.</param>
+ /// <param name="source15">Fifteenth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="source12"/> or <paramref name="source13"/> or <paramref name="source14"/> or <paramref name="source15"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, IObservable<TSource15> source15, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (source12 == null)
+ throw new ArgumentNullException("source12");
+ if (source13 == null)
+ throw new ArgumentNullException("source13");
+ if (source14 == null)
+ throw new ArgumentNullException("source14");
+ if (source15 == null)
+ throw new ArgumentNullException("source15");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
+ /// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
+ /// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
+ /// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
+ /// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
+ /// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
+ /// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
+ /// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
+ /// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>
+ /// <typeparam name="TSource11">The type of the elements in the eleventh source sequence.</typeparam>
+ /// <typeparam name="TSource12">The type of the elements in the twelfth source sequence.</typeparam>
+ /// <typeparam name="TSource13">The type of the elements in the thirteenth source sequence.</typeparam>
+ /// <typeparam name="TSource14">The type of the elements in the fourteenth source sequence.</typeparam>
+ /// <typeparam name="TSource15">The type of the elements in the fifteenth source sequence.</typeparam>
+ /// <typeparam name="TSource16">The type of the elements in the sixteenth source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="source1">First observable source.</param>
+ /// <param name="source2">Second observable source.</param>
+ /// <param name="source3">Third observable source.</param>
+ /// <param name="source4">Fourth observable source.</param>
+ /// <param name="source5">Fifth observable source.</param>
+ /// <param name="source6">Sixth observable source.</param>
+ /// <param name="source7">Seventh observable source.</param>
+ /// <param name="source8">Eighth observable source.</param>
+ /// <param name="source9">Ninth observable source.</param>
+ /// <param name="source10">Tenth observable source.</param>
+ /// <param name="source11">Eleventh observable source.</param>
+ /// <param name="source12">Twelfth observable source.</param>
+ /// <param name="source13">Thirteenth observable source.</param>
+ /// <param name="source14">Fourteenth observable source.</param>
+ /// <param name="source15">Fifteenth observable source.</param>
+ /// <param name="source16">Sixteenth observable source.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="source4"/> or <paramref name="source5"/> or <paramref name="source6"/> or <paramref name="source7"/> or <paramref name="source8"/> or <paramref name="source9"/> or <paramref name="source10"/> or <paramref name="source11"/> or <paramref name="source12"/> or <paramref name="source13"/> or <paramref name="source14"/> or <paramref name="source15"/> or <paramref name="source16"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, IObservable<TSource15> source15, IObservable<TSource16> source16, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult> resultSelector)
+ {
+ if (source1 == null)
+ throw new ArgumentNullException("source1");
+ if (source2 == null)
+ throw new ArgumentNullException("source2");
+ if (source3 == null)
+ throw new ArgumentNullException("source3");
+ if (source4 == null)
+ throw new ArgumentNullException("source4");
+ if (source5 == null)
+ throw new ArgumentNullException("source5");
+ if (source6 == null)
+ throw new ArgumentNullException("source6");
+ if (source7 == null)
+ throw new ArgumentNullException("source7");
+ if (source8 == null)
+ throw new ArgumentNullException("source8");
+ if (source9 == null)
+ throw new ArgumentNullException("source9");
+ if (source10 == null)
+ throw new ArgumentNullException("source10");
+ if (source11 == null)
+ throw new ArgumentNullException("source11");
+ if (source12 == null)
+ throw new ArgumentNullException("source12");
+ if (source13 == null)
+ throw new ArgumentNullException("source13");
+ if (source14 == null)
+ throw new ArgumentNullException("source14");
+ if (source15 == null)
+ throw new ArgumentNullException("source15");
+ if (source16 == null)
+ throw new ArgumentNullException("source16");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, source16, resultSelector);
+ }
+
+#endif
+
+ #endregion
+
+#endif
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="sources">Observable sources.</param>
+ /// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
+ /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource, TResult>(this IEnumerable<IObservable<TSource>> sources, Func<IList<TSource>, TResult> resultSelector)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource, TResult>(sources, resultSelector);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by emitting a list with the elements of the observable sequences at corresponding indexes.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences, and in the lists in the result sequence.</typeparam>
+ /// <param name="sources">Observable sources.</param>
+ /// <returns>An observable sequence containing lists of elements at corresponding indexes.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<IList<TSource>> Zip<TSource>(this IEnumerable<IObservable<TSource>> sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Zip<TSource>(sources);
+ }
+
+ /// <summary>
+ /// Merges the specified observable sequences into one observable sequence by emitting a list with the elements of the observable sequences at corresponding indexes.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequences, and in the lists in the result sequence.</typeparam>
+ /// <param name="sources">Observable sources.</param>
+ /// <returns>An observable sequence containing lists of elements at corresponding indexes.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
+ public static IObservable<IList<TSource>> Zip<TSource>(params IObservable<TSource>[] sources)
+ {
+ if (sources == null)
+ throw new ArgumentNullException("sources");
+
+ return s_impl.Zip<TSource>(sources);
+ }
+
+ /// <summary>
+ /// Merges an observable sequence and an enumerable sequence into one observable sequence by using the selector function.
+ /// </summary>
+ /// <typeparam name="TSource1">The type of the elements in the first observable source sequence.</typeparam>
+ /// <typeparam name="TSource2">The type of the elements in the second enumerable source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
+ /// <param name="first">First observable source.</param>
+ /// <param name="second">Second enumerable source.</param>
+ /// <param name="resultSelector">Function to invoke for each consecutive pair of elements from the first and second source.</param>
+ /// <returns>An observable sequence containing the result of pairwise combining the elements of the first and second source using the specified result selector function.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Zip<TSource1, TSource2, TResult>(this IObservable<TSource1> first, IEnumerable<TSource2> second, Func<TSource1, TSource2, TResult> resultSelector)
+ {
+ if (first == null)
+ throw new ArgumentNullException("first");
+ if (second == null)
+ throw new ArgumentNullException("second");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Zip<TSource1, TSource2, TResult>(first, second, resultSelector);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Single.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Single.cs
new file mode 100644
index 0000000..749f823
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Single.cs
@@ -0,0 +1,657 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region + AsObservable +
+
+ /// <summary>
+ /// Hides the identity of an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence whose identity to hide.</param>
+ /// <returns>An observable sequence that hides the identity of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> AsObservable<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.AsObservable<TSource>(source);
+ }
+
+ #endregion
+
+ #region + Buffer +
+
+ /// <summary>
+ /// Projects each element of an observable sequence into consecutive non-overlapping buffers which are produced based on element count information.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="count">Length of each buffer.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than or equal to zero.</exception>
+ public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, int count)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count <= 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ return s_impl.Buffer<TSource>(source, count);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="count">Length of each buffer.</param>
+ /// <param name="skip">Number of elements to skip between creation of consecutive buffers.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> or <paramref name="skip"/> is less than or equal to zero.</exception>
+ public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, int count, int skip)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count <= 0)
+ throw new ArgumentOutOfRangeException("count");
+ if (skip <= 0)
+ throw new ArgumentOutOfRangeException("skip");
+
+ return s_impl.Buffer<TSource>(source, count, skip);
+ }
+
+ #endregion
+
+ #region + Dematerialize +
+
+ /// <summary>
+ /// Dematerializes the explicit notification values of an observable sequence as implicit notifications.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements materialized in the source sequence notification objects.</typeparam>
+ /// <param name="source">An observable sequence containing explicit notification values which have to be turned into implicit notifications.</param>
+ /// <returns>An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> Dematerialize<TSource>(this IObservable<Notification<TSource>> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Dematerialize<TSource>(source);
+ }
+
+ #endregion
+
+ #region + DistinctUntilChanged +
+
+ /// <summary>
+ /// Returns an observable sequence that contains only distinct contiguous elements.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to retain distinct contiguous elements for.</param>
+ /// <returns>An observable sequence only containing the distinct contiguous elements from the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> DistinctUntilChanged<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.DistinctUntilChanged<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that contains only distinct contiguous elements according to the comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to retain distinct contiguous elements for.</param>
+ /// <param name="comparer">Equality comparer for source elements.</param>
+ /// <returns>An observable sequence only containing the distinct contiguous elements from the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="comparer"/> is null.</exception>
+ public static IObservable<TSource> DistinctUntilChanged<TSource>(this IObservable<TSource> source, IEqualityComparer<TSource> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.DistinctUntilChanged<TSource>(source, comparer);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that contains only distinct contiguous elements according to the keySelector.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the discriminator key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to retain distinct contiguous elements for, based on a computed key value.</param>
+ /// <param name="keySelector">A function to compute the comparison key for each element.</param>
+ /// <returns>An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
+ public static IObservable<TSource> DistinctUntilChanged<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+
+ return s_impl.DistinctUntilChanged<TSource, TKey>(source, keySelector);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that contains only distinct contiguous elements according to the keySelector and the comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the discriminator key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to retain distinct contiguous elements for, based on a computed key value.</param>
+ /// <param name="keySelector">A function to compute the comparison key for each element.</param>
+ /// <param name="comparer">Equality comparer for computed key values.</param>
+ /// <returns>An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="comparer"/> is null.</exception>
+ public static IObservable<TSource> DistinctUntilChanged<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.DistinctUntilChanged<TSource, TKey>(source, keySelector, comparer);
+ }
+
+ #endregion
+
+ #region + Do +
+
+ /// <summary>
+ /// Invokes an action for each element in the observable sequence, and propagates all observer messages through the result sequence.
+ /// This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
+ /// <returns>The source sequence with the side-effecting behavior applied.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
+ public static IObservable<TSource> Do<TSource>(this IObservable<TSource> source, Action<TSource> onNext)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+
+ return s_impl.Do<TSource>(source, onNext);
+ }
+
+ /// <summary>
+ /// Invokes an action for each element in the observable sequence and invokes an action upon graceful termination of the observable sequence.
+ /// This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
+ /// <param name="onCompleted">Action to invoke upon graceful termination of the observable sequence.</param>
+ /// <returns>The source sequence with the side-effecting behavior applied.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> or <paramref name="onCompleted"/> is null.</exception>
+ public static IObservable<TSource> Do<TSource>(this IObservable<TSource> source, Action<TSource> onNext, Action onCompleted)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+ if (onCompleted == null)
+ throw new ArgumentNullException("onCompleted");
+
+ return s_impl.Do<TSource>(source, onNext, onCompleted);
+ }
+
+ /// <summary>
+ /// Invokes an action for each element in the observable sequence and invokes an action upon exceptional termination of the observable sequence.
+ /// This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
+ /// <param name="onError">Action to invoke upon exceptional termination of the observable sequence.</param>
+ /// <returns>The source sequence with the side-effecting behavior applied.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> or <paramref name="onError"/> is null.</exception>
+ public static IObservable<TSource> Do<TSource>(this IObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+ if (onError == null)
+ throw new ArgumentNullException("onError");
+
+ return s_impl.Do<TSource>(source, onNext, onError);
+ }
+
+ /// <summary>
+ /// Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
+ /// This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
+ /// <param name="onError">Action to invoke upon exceptional termination of the observable sequence.</param>
+ /// <param name="onCompleted">Action to invoke upon graceful termination of the observable sequence.</param>
+ /// <returns>The source sequence with the side-effecting behavior applied.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> or <paramref name="onError"/> or <paramref name="onCompleted"/> is null.</exception>
+ public static IObservable<TSource> Do<TSource>(this IObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+ if (onError == null)
+ throw new ArgumentNullException("onError");
+ if (onCompleted == null)
+ throw new ArgumentNullException("onCompleted");
+
+ return s_impl.Do<TSource>(source, onNext, onError, onCompleted);
+ }
+
+ /// <summary>
+ /// Invokes the observer's methods for each message in the source sequence.
+ /// This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="observer">Observer whose methods to invoke as part of the source sequence's observation.</param>
+ /// <returns>The source sequence with the side-effecting behavior applied.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="observer"/> is null.</exception>
+ public static IObservable<TSource> Do<TSource>(this IObservable<TSource> source, IObserver<TSource> observer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (observer == null)
+ throw new ArgumentNullException("observer");
+
+ return s_impl.Do<TSource>(source, observer);
+ }
+
+ #endregion
+
+ #region + Finally +
+
+ /// <summary>
+ /// Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="finallyAction">Action to invoke after the source observable sequence terminates.</param>
+ /// <returns>Source sequence with the action-invoking termination behavior applied.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="finallyAction"/> is null.</exception>
+ public static IObservable<TSource> Finally<TSource>(this IObservable<TSource> source, Action finallyAction)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (finallyAction == null)
+ throw new ArgumentNullException("finallyAction");
+
+ return s_impl.Finally<TSource>(source, finallyAction);
+ }
+
+ #endregion
+
+ #region + IgnoreElements +
+
+ /// <summary>
+ /// Ignores all elements in an observable sequence leaving only the termination messages.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <returns>An empty observable sequence that signals termination, successful or exceptional, of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> IgnoreElements<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.IgnoreElements<TSource>(source);
+ }
+
+ #endregion
+
+ #region + Materialize +
+
+ /// <summary>
+ /// Materializes the implicit notifications of an observable sequence as explicit notification values.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to get notification values for.</param>
+ /// <returns>An observable sequence containing the materialized notification values from the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<Notification<TSource>> Materialize<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Materialize<TSource>(source);
+ }
+
+ #endregion
+
+ #region - Repeat -
+
+ /// <summary>
+ /// Repeats the observable sequence indefinitely.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Observable sequence to repeat.</param>
+ /// <returns>The observable sequence producing the elements of the given sequence repeatedly and sequentially.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> Repeat<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Repeat<TSource>(source);
+ }
+
+ /// <summary>
+ /// Repeats the observable sequence a specified number of times.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Observable sequence to repeat.</param>
+ /// <param name="repeatCount">Number of times to repeat the sequence.</param>
+ /// <returns>The observable sequence producing the elements of the given sequence repeatedly.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="repeatCount"/> is less than zero.</exception>
+ public static IObservable<TSource> Repeat<TSource>(this IObservable<TSource> source, int repeatCount)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (repeatCount < 0)
+ throw new ArgumentOutOfRangeException("repeatCount");
+
+ return s_impl.Repeat<TSource>(source, repeatCount);
+ }
+
+ #endregion
+
+ #region - Retry -
+
+ /// <summary>
+ /// Repeats the source observable sequence until it successfully terminates.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Observable sequence to repeat until it successfully terminates.</param>
+ /// <returns>An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> Retry<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Retry<TSource>(source);
+ }
+
+ /// <summary>
+ /// Repeats the source observable sequence the specified number of times or until it successfully terminates.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Observable sequence to repeat until it successfully terminates.</param>
+ /// <param name="retryCount">Number of times to repeat the sequence.</param>
+ /// <returns>An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="retryCount"/> is less than zero.</exception>
+ public static IObservable<TSource> Retry<TSource>(this IObservable<TSource> source, int retryCount)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (retryCount < 0)
+ throw new ArgumentOutOfRangeException("retryCount");
+
+ return s_impl.Retry<TSource>(source, retryCount);
+ }
+
+ #endregion
+
+ #region + Scan +
+
+ /// <summary>
+ /// Applies an accumulator function over an observable sequence and returns each intermediate result. The specified seed value is used as the initial accumulator value.
+ /// For aggregation behavior with no intermediate results, see <see cref="Observable.Aggregate&lt;TSource, Accumulate&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TAccumulate">The type of the result of the aggregation.</typeparam>
+ /// <param name="source">An observable sequence to accumulate over.</param>
+ /// <param name="seed">The initial accumulator value.</param>
+ /// <param name="accumulator">An accumulator function to be invoked on each element.</param>
+ /// <returns>An observable sequence containing the accumulated values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="accumulator"/> is null.</exception>
+ public static IObservable<TAccumulate> Scan<TSource, TAccumulate>(this IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (accumulator == null)
+ throw new ArgumentNullException("accumulator");
+
+ return s_impl.Scan<TSource, TAccumulate>(source, seed, accumulator);
+ }
+
+ /// <summary>
+ /// Applies an accumulator function over an observable sequence and returns each intermediate result.
+ /// For aggregation behavior with no intermediate results, see <see cref="Observable.Aggregate&lt;TSource&gt;"/>.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence and the result of the aggregation.</typeparam>
+ /// <param name="source">An observable sequence to accumulate over.</param>
+ /// <param name="accumulator">An accumulator function to be invoked on each element.</param>
+ /// <returns>An observable sequence containing the accumulated values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="accumulator"/> is null.</exception>
+ public static IObservable<TSource> Scan<TSource>(this IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (accumulator == null)
+ throw new ArgumentNullException("accumulator");
+
+ return s_impl.Scan<TSource>(source, accumulator);
+ }
+
+ #endregion
+
+ #region + SkipLast +
+
+ /// <summary>
+ /// Bypasses a specified number of elements at the end of an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="count">Number of elements to bypass at the end of the source sequence.</param>
+ /// <returns>An observable sequence containing the source sequence elements except for the bypassed ones at the end.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a queue with a length enough to store the first <paramref name="count"/> elements. As more elements are
+ /// received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
+ /// </remarks>
+ public static IObservable<TSource> SkipLast<TSource>(this IObservable<TSource> source, int count)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ return s_impl.SkipLast<TSource>(source, count);
+ }
+
+ #endregion
+
+ #region - StartWith -
+
+ /// <summary>
+ /// Prepends a sequence of values to an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to prepend values to.</param>
+ /// <param name="values">Values to prepend to the specified sequence.</param>
+ /// <returns>The source sequence prepended with the specified values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="values"/> is null.</exception>
+ public static IObservable<TSource> StartWith<TSource>(this IObservable<TSource> source, params TSource[] values)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (values == null)
+ throw new ArgumentNullException("values");
+
+ return s_impl.StartWith<TSource>(source, values);
+ }
+
+ /// <summary>
+ /// Prepends a sequence of values to an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to prepend values to.</param>
+ /// <param name="scheduler">Scheduler to emit the prepended values on.</param>
+ /// <param name="values">Values to prepend to the specified sequence.</param>
+ /// <returns>The source sequence prepended with the specified values.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> or <paramref name="values"/> is null.</exception>
+ public static IObservable<TSource> StartWith<TSource>(this IObservable<TSource> source, IScheduler scheduler, params TSource[] values)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+ if (values == null)
+ throw new ArgumentNullException("values");
+
+ return s_impl.StartWith<TSource>(source, scheduler, values);
+ }
+
+ #endregion
+
+ #region + TakeLast +
+
+ /// <summary>
+ /// Returns a specified number of contiguous elements from the end of an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="count">Number of elements to take from the end of the source sequence.</param>
+ /// <returns>An observable sequence containing the specified number of elements from the end of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a buffer with a length enough to store elements <paramref name="count"/> elements. Upon completion of
+ /// the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
+ /// </remarks>
+ public static IObservable<TSource> TakeLast<TSource>(this IObservable<TSource> source, int count)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ return s_impl.TakeLast<TSource>(source, count);
+ }
+
+ /// <summary>
+ /// Returns a specified number of contiguous elements from the end of an observable sequence, using the specified scheduler to drain the queue.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="count">Number of elements to take from the end of the source sequence.</param>
+ /// <param name="scheduler">Scheduler used to drain the queue upon completion of the source sequence.</param>
+ /// <returns>An observable sequence containing the specified number of elements from the end of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a buffer with a length enough to store elements <paramref name="count"/> elements. Upon completion of
+ /// the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
+ /// </remarks>
+ public static IObservable<TSource> TakeLast<TSource>(this IObservable<TSource> source, int count, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.TakeLast<TSource>(source, count, scheduler);
+ }
+
+ #endregion
+
+ #region + TakeLastBuffer +
+
+ /// <summary>
+ /// Returns a list with the specified number of contiguous elements from the end of an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence.</param>
+ /// <param name="count">Number of elements to take from the end of the source sequence.</param>
+ /// <returns>An observable sequence containing a single list with the specified number of elements from the end of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a buffer with a length enough to store <paramref name="count"/> elements. Upon completion of the
+ /// source sequence, this buffer is produced on the result sequence.
+ /// </remarks>
+ public static IObservable<IList<TSource>> TakeLastBuffer<TSource>(this IObservable<TSource> source, int count)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ return s_impl.TakeLastBuffer<TSource>(source, count);
+ }
+
+ #endregion
+
+ #region + Window +
+
+ /// <summary>
+ /// Projects each element of an observable sequence into consecutive non-overlapping windows which are produced based on element count information.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="count">Length of each window.</param>
+ /// <returns>An observable sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than or equal to zero.</exception>
+ public static IObservable<IObservable<TSource>> Window<TSource>(this IObservable<TSource> source, int count)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count <= 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ return s_impl.Window<TSource>(source, count);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="count">Length of each window.</param>
+ /// <param name="skip">Number of elements to skip between creation of consecutive windows.</param>
+ /// <returns>An observable sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> or <paramref name="skip"/> is less than or equal to zero.</exception>
+ public static IObservable<IObservable<TSource>> Window<TSource>(this IObservable<TSource> source, int count, int skip)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count <= 0)
+ throw new ArgumentOutOfRangeException("count");
+ if (skip <= 0)
+ throw new ArgumentOutOfRangeException("skip");
+
+ return s_impl.Window<TSource>(source, count, skip);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.StandardSequenceOperators.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.StandardSequenceOperators.cs
new file mode 100644
index 0000000..e20e3eb
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.StandardSequenceOperators.cs
@@ -0,0 +1,923 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+
+#if !NO_TPL
+using System.Reactive.Threading.Tasks; // needed for doc comments
+using System.Threading;
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region + Cast +
+
+ /// <summary>
+ /// Converts the elements of an observable sequence to the specified type.
+ /// </summary>
+ /// <typeparam name="TResult">The type to convert the elements in the source sequence to.</typeparam>
+ /// <param name="source">The observable sequence that contains the elements to be converted.</param>
+ /// <returns>An observable sequence that contains each element of the source sequence converted to the specified type.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TResult> Cast<TResult>(this IObservable<object> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Cast<TResult>(source);
+ }
+
+ #endregion
+
+ #region + DefaultIfEmpty +
+
+ /// <summary>
+ /// Returns the elements of the specified sequence or the type parameter's default value in a singleton sequence if the sequence is empty.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence (if any), whose default value will be taken if the sequence is empty.</typeparam>
+ /// <param name="source">The sequence to return a default value for if it is empty.</param>
+ /// <returns>An observable sequence that contains the default value for the TSource type if the source is empty; otherwise, the elements of the source itself.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> DefaultIfEmpty<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.DefaultIfEmpty<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence (if any), and the specified default value which will be taken if the sequence is empty.</typeparam>
+ /// <param name="source">The sequence to return the specified value for if it is empty.</param>
+ /// <param name="defaultValue">The value to return if the sequence is empty.</param>
+ /// <returns>An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> DefaultIfEmpty<TSource>(this IObservable<TSource> source, TSource defaultValue)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.DefaultIfEmpty<TSource>(source, defaultValue);
+ }
+
+ #endregion
+
+ #region + Distinct +
+
+ /// <summary>
+ /// Returns an observable sequence that contains only distinct elements.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to retain distinct elements for.</param>
+ /// <returns>An observable sequence only containing the distinct elements from the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.</remarks>
+ public static IObservable<TSource> Distinct<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Distinct<TSource>(source);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that contains only distinct elements according to the comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to retain distinct elements for.</param>
+ /// <param name="comparer">Equality comparer for source elements.</param>
+ /// <returns>An observable sequence only containing the distinct elements from the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.</remarks>
+ public static IObservable<TSource> Distinct<TSource>(this IObservable<TSource> source, IEqualityComparer<TSource> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.Distinct<TSource>(source, comparer);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that contains only distinct elements according to the keySelector.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the discriminator key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to retain distinct elements for.</param>
+ /// <param name="keySelector">A function to compute the comparison key for each element.</param>
+ /// <returns>An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
+ /// <remarks>Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.</remarks>
+ public static IObservable<TSource> Distinct<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+
+ return s_impl.Distinct<TSource, TKey>(source, keySelector);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the discriminator key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to retain distinct elements for.</param>
+ /// <param name="keySelector">A function to compute the comparison key for each element.</param>
+ /// <param name="comparer">Equality comparer for source elements.</param>
+ /// <returns>An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="comparer"/> is null.</exception>
+ /// <remarks>Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.</remarks>
+ public static IObservable<TSource> Distinct<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.Distinct<TSource, TKey>(source, keySelector, comparer);
+ }
+
+ #endregion
+
+ #region + GroupBy +
+
+ /// <summary>
+ /// Groups the elements of an observable sequence according to a specified key selector function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the grouping key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence whose elements to group.</param>
+ /// <param name="keySelector">A function to extract the key for each element.</param>
+ /// <returns>A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
+ public static IObservable<IGroupedObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+
+ return s_impl.GroupBy<TSource, TKey>(source, keySelector);
+ }
+
+ /// <summary>
+ /// Groups the elements of an observable sequence according to a specified key selector function and comparer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the grouping key computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence whose elements to group.</param>
+ /// <param name="keySelector">A function to extract the key for each element.</param>
+ /// <param name="comparer">An equality comparer to compare keys with.</param>
+ /// <returns>A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="comparer"/> is null.</exception>
+ public static IObservable<IGroupedObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.GroupBy<TSource, TKey>(source, keySelector, comparer);
+ }
+
+ /// <summary>
+ /// Groups the elements of an observable sequence and selects the resulting elements by using a specified function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the grouping key computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TElement">The type of the elements within the groups computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence whose elements to group.</param>
+ /// <param name="keySelector">A function to extract the key for each element.</param>
+ /// <param name="elementSelector">A function to map each source element to an element in an observable group.</param>
+ /// <returns>A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> is null.</exception>
+ public static IObservable<IGroupedObservable<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (elementSelector == null)
+ throw new ArgumentNullException("elementSelector");
+
+ return s_impl.GroupBy<TSource, TKey, TElement>(source, keySelector, elementSelector);
+ }
+
+ /// <summary>
+ /// Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the grouping key computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TElement">The type of the elements within the groups computed for each element in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence whose elements to group.</param>
+ /// <param name="keySelector">A function to extract the key for each element.</param>
+ /// <param name="elementSelector">A function to map each source element to an element in an observable group.</param>
+ /// <param name="comparer">An equality comparer to compare keys with.</param>
+ /// <returns>A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> or <paramref name="comparer"/> is null.</exception>
+ public static IObservable<IGroupedObservable<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (elementSelector == null)
+ throw new ArgumentNullException("elementSelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.GroupBy<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
+ }
+
+ #endregion
+
+ #region + GroupByUntil +
+
+ /// <summary>
+ /// Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function.
+ /// A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same
+ /// key value as a reclaimed group occurs, the group will be reborn with a new lifetime request.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the grouping key computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TElement">The type of the elements within the groups computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TDuration">The type of the elements in the duration sequences obtained for each group to denote its lifetime.</typeparam>
+ /// <param name="source">An observable sequence whose elements to group.</param>
+ /// <param name="keySelector">A function to extract the key for each element.</param>
+ /// <param name="elementSelector">A function to map each source element to an element in an observable group.</param>
+ /// <param name="durationSelector">A function to signal the expiration of a group.</param>
+ /// <param name="comparer">An equality comparer to compare keys with.</param>
+ /// <returns>
+ /// A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
+ /// If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encountered.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> or <paramref name="durationSelector"/> or <paramref name="comparer"/> is null.</exception>
+ public static IObservable<IGroupedObservable<TKey, TElement>> GroupByUntil<TSource, TKey, TElement, TDuration>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedObservable<TKey, TElement>, IObservable<TDuration>> durationSelector, IEqualityComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (elementSelector == null)
+ throw new ArgumentNullException("elementSelector");
+ if (durationSelector == null)
+ throw new ArgumentNullException("durationSelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.GroupByUntil<TSource, TKey, TElement, TDuration>(source, keySelector, elementSelector, durationSelector, comparer);
+ }
+
+ /// <summary>
+ /// Groups the elements of an observable sequence according to a specified key selector function and selects the resulting elements by using a specified function.
+ /// A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same
+ /// key value as a reclaimed group occurs, the group will be reborn with a new lifetime request.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the grouping key computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TElement">The type of the elements within the groups computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TDuration">The type of the elements in the duration sequences obtained for each group to denote its lifetime.</typeparam>
+ /// <param name="source">An observable sequence whose elements to group.</param>
+ /// <param name="keySelector">A function to extract the key for each element.</param>
+ /// <param name="elementSelector">A function to map each source element to an element in an observable group.</param>
+ /// <param name="durationSelector">A function to signal the expiration of a group.</param>
+ /// <returns>
+ /// A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
+ /// If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encoutered.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> or <paramref name="durationSelector"/> is null.</exception>
+ public static IObservable<IGroupedObservable<TKey, TElement>> GroupByUntil<TSource, TKey, TElement, TDuration>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedObservable<TKey, TElement>, IObservable<TDuration>> durationSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (elementSelector == null)
+ throw new ArgumentNullException("elementSelector");
+ if (durationSelector == null)
+ throw new ArgumentNullException("durationSelector");
+
+ return s_impl.GroupByUntil<TSource, TKey, TElement, TDuration>(source, keySelector, elementSelector, durationSelector);
+ }
+
+ /// <summary>
+ /// Groups the elements of an observable sequence according to a specified key selector function and comparer.
+ /// A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same
+ /// key value as a reclaimed group occurs, the group will be reborn with a new lifetime request.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the grouping key computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TDuration">The type of the elements in the duration sequences obtained for each group to denote its lifetime.</typeparam>
+ /// <param name="source">An observable sequence whose elements to group.</param>
+ /// <param name="keySelector">A function to extract the key for each element.</param>
+ /// <param name="durationSelector">A function to signal the expiration of a group.</param>
+ /// <param name="comparer">An equality comparer to compare keys with.</param>
+ /// <returns>
+ /// A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
+ /// If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encoutered.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="durationSelector"/> or <paramref name="comparer"/> is null.</exception>
+ public static IObservable<IGroupedObservable<TKey, TSource>> GroupByUntil<TSource, TKey, TDuration>(this IObservable<TSource> source, Func<TSource, TKey> keySelector,Func<IGroupedObservable<TKey, TSource>, IObservable<TDuration>> durationSelector, IEqualityComparer<TKey> comparer)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (durationSelector == null)
+ throw new ArgumentNullException("durationSelector");
+ if (comparer == null)
+ throw new ArgumentNullException("comparer");
+
+ return s_impl.GroupByUntil<TSource, TKey, TDuration>(source, keySelector, durationSelector, comparer);
+ }
+
+ /// <summary>
+ /// Groups the elements of an observable sequence according to a specified key selector function.
+ /// A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same
+ /// key value as a reclaimed group occurs, the group will be reborn with a new lifetime request.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TKey">The type of the grouping key computed for each element in the source sequence.</typeparam>
+ /// <typeparam name="TDuration">The type of the elements in the duration sequences obtained for each group to denote its lifetime.</typeparam>
+ /// <param name="source">An observable sequence whose elements to group.</param>
+ /// <param name="keySelector">A function to extract the key for each element.</param>
+ /// <param name="durationSelector">A function to signal the expiration of a group.</param>
+ /// <returns>
+ /// A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
+ /// If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encoutered.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="durationSelector"/> is null.</exception>
+ public static IObservable<IGroupedObservable<TKey, TSource>> GroupByUntil<TSource, TKey, TDuration>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<IGroupedObservable<TKey, TSource>, IObservable<TDuration>> durationSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (keySelector == null)
+ throw new ArgumentNullException("keySelector");
+ if (durationSelector == null)
+ throw new ArgumentNullException("durationSelector");
+
+ return s_impl.GroupByUntil<TSource, TKey, TDuration>(source, keySelector, durationSelector);
+ }
+
+ #endregion
+
+ #region + GroupJoin +
+
+ /// <summary>
+ /// Correlates the elements of two sequences based on overlapping durations, and groups the results.
+ /// </summary>
+ /// <typeparam name="TLeft">The type of the elements in the left source sequence.</typeparam>
+ /// <typeparam name="TRight">The type of the elements in the right source sequence.</typeparam>
+ /// <typeparam name="TLeftDuration">The type of the elements in the duration sequence denoting the computed duration of each element in the left source sequence.</typeparam>
+ /// <typeparam name="TRightDuration">The type of the elements in the duration sequence denoting the computed duration of each element in the right source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, obtained by invoking the result selector function for source elements with overlapping duration.</typeparam>
+ /// <param name="left">The left observable sequence to join elements for.</param>
+ /// <param name="right">The right observable sequence to join elements for.</param>
+ /// <param name="leftDurationSelector">A function to select the duration of each element of the left observable sequence, used to determine overlap.</param>
+ /// <param name="rightDurationSelector">A function to select the duration of each element of the right observable sequence, used to determine overlap.</param>
+ /// <param name="resultSelector">A function invoked to compute a result element for any element of the left sequence with overlapping elements from the right observable sequence.</param>
+ /// <returns>An observable sequence that contains result elements computed from source elements that have an overlapping duration.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> or <paramref name="leftDurationSelector"/> or <paramref name="rightDurationSelector"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(this IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, IObservable<TRight>, TResult> resultSelector)
+ {
+ if (left == null)
+ throw new ArgumentNullException("left");
+ if (right == null)
+ throw new ArgumentNullException("right");
+ if (leftDurationSelector == null)
+ throw new ArgumentNullException("leftDurationSelector");
+ if (rightDurationSelector == null)
+ throw new ArgumentNullException("rightDurationSelector");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(left, right, leftDurationSelector, rightDurationSelector, resultSelector);
+ }
+
+ #endregion
+
+ #region + Join +
+
+ /// <summary>
+ /// Correlates the elements of two sequences based on overlapping durations.
+ /// </summary>
+ /// <typeparam name="TLeft">The type of the elements in the left source sequence.</typeparam>
+ /// <typeparam name="TRight">The type of the elements in the right source sequence.</typeparam>
+ /// <typeparam name="TLeftDuration">The type of the elements in the duration sequence denoting the computed duration of each element in the left source sequence.</typeparam>
+ /// <typeparam name="TRightDuration">The type of the elements in the duration sequence denoting the computed duration of each element in the right source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, obtained by invoking the result selector function for source elements with overlapping duration.</typeparam>
+ /// <param name="left">The left observable sequence to join elements for.</param>
+ /// <param name="right">The right observable sequence to join elements for.</param>
+ /// <param name="leftDurationSelector">A function to select the duration of each element of the left observable sequence, used to determine overlap.</param>
+ /// <param name="rightDurationSelector">A function to select the duration of each element of the right observable sequence, used to determine overlap.</param>
+ /// <param name="resultSelector">A function invoked to compute a result element for any two overlapping elements of the left and right observable sequences.</param>
+ /// <returns>An observable sequence that contains result elements computed from source elements that have an overlapping duration.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> or <paramref name="leftDurationSelector"/> or <paramref name="rightDurationSelector"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(this IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, TRight, TResult> resultSelector)
+ {
+ if (left == null)
+ throw new ArgumentNullException("left");
+ if (right == null)
+ throw new ArgumentNullException("right");
+ if (leftDurationSelector == null)
+ throw new ArgumentNullException("leftDurationSelector");
+ if (rightDurationSelector == null)
+ throw new ArgumentNullException("rightDurationSelector");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(left, right, leftDurationSelector, rightDurationSelector, resultSelector);
+ }
+
+ #endregion
+
+ #region + OfType +
+
+ /// <summary>
+ /// Filters the elements of an observable sequence based on the specified type.
+ /// </summary>
+ /// <typeparam name="TResult">The type to filter the elements in the source sequence on.</typeparam>
+ /// <param name="source">The observable sequence that contains the elements to be filtered.</param>
+ /// <returns>An observable sequence that contains elements from the input sequence of type TResult.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TResult> OfType<TResult>(this IObservable<object> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.OfType<TResult>(source);
+ }
+
+ #endregion
+
+ #region + Select +
+
+ /// <summary>
+ /// Projects each element of an observable sequence into a new form.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, obtained by running the selector function for each element in the source sequence.</typeparam>
+ /// <param name="source">A sequence of elements to invoke a transform function on.</param>
+ /// <param name="selector">A transform function to apply to each source element.</param>
+ /// <returns>An observable sequence whose elements are the result of invoking the transform function on each element of source.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ public static IObservable<TResult> Select<TSource, TResult>(this IObservable<TSource> source, Func<TSource, TResult> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Select<TSource, TResult>(source, selector);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into a new form by incorporating the element's index.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, obtained by running the selector function for each element in the source sequence.</typeparam>
+ /// <param name="source">A sequence of elements to invoke a transform function on.</param>
+ /// <param name="selector">A transform function to apply to each source element; the second parameter of the function represents the index of the source element.</param>
+ /// <returns>An observable sequence whose elements are the result of invoking the transform function on each element of source.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ public static IObservable<TResult> Select<TSource, TResult>(this IObservable<TSource> source, Func<TSource, int, TResult> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.Select<TSource, TResult>(source, selector);
+ }
+
+ #endregion
+
+ #region + SelectMany +
+
+ /// <summary>
+ /// Projects each element of the source observable sequence to the other observable sequence and merges the resulting observable sequences into one observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TOther">The type of the elements in the other sequence and the elements in the result sequence.</typeparam>
+ /// <param name="source">An observable sequence of elements to project.</param>
+ /// <param name="other">An observable sequence to project each element from the source sequence onto.</param>
+ /// <returns>An observable sequence whose elements are the result of projecting each source element onto the other sequence and merging all the resulting sequences together.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="other"/> is null.</exception>
+ public static IObservable<TOther> SelectMany<TSource, TOther>(this IObservable<TSource> source, IObservable<TOther> other)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (other == null)
+ throw new ArgumentNullException("other");
+
+ return s_impl.SelectMany<TSource, TOther>(source, other);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the projected inner sequences and the elements in the merged result sequence.</typeparam>
+ /// <param name="source">An observable sequence of elements to project.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ public static IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.SelectMany<TSource, TResult>(source, selector);
+ }
+
+#if !NO_TPL
+ /// <summary>
+ /// Projects each element of an observable sequence to a task and merges all of the task results into one observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the result produced by the projected tasks and the elements in the merged result sequence.</typeparam>
+ /// <param name="source">An observable sequence of elements to project.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence whose elements are the result of the tasks executed for each element of the input sequence.</returns>
+ /// <remarks>This overload supports composition of observable sequences and tasks, without requiring manual conversion of the tasks to observable sequences using <see cref="TaskObservableExtensions.ToObservable&lt;TResult&gt;"/>.</remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ public static IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, Task<TResult>> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.SelectMany<TSource, TResult>(source, selector);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence to a task with cancellation support and merges all of the task results into one observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the result produced by the projected tasks and the elements in the merged result sequence.</typeparam>
+ /// <param name="source">An observable sequence of elements to project.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence whose elements are the result of the tasks executed for each element of the input sequence.</returns>
+ /// <remarks>This overload supports composition of observable sequences and tasks, without requiring manual conversion of the tasks to observable sequences using <see cref="TaskObservableExtensions.ToObservable&lt;TResult&gt;"/>.</remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ public static IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, CancellationToken, Task<TResult>> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.SelectMany<TSource, TResult>(source, selector);
+ }
+#endif
+
+ /// <summary>
+ /// Projects each element of an observable sequence to an observable sequence, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and merges the results into one observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TCollection">The type of the elements in the projected intermediate sequences.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, obtained by using the selector to combine source sequence elements with their corresponding intermediate sequence elements.</typeparam>
+ /// <param name="source">An observable sequence of elements to project.</param>
+ /// <param name="collectionSelector">A transform function to apply to each element.</param>
+ /// <param name="resultSelector">A transform function to apply to each element of the intermediate sequence.</param>
+ /// <returns>An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="collectionSelector"/> or <paramref name="resultSelector"/> is null.</exception>
+ public static IObservable<TResult> SelectMany<TSource, TCollection, TResult>(this IObservable<TSource> source, Func<TSource, IObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (collectionSelector == null)
+ throw new ArgumentNullException("collectionSelector");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.SelectMany<TSource, TCollection, TResult>(source, collectionSelector, resultSelector);
+ }
+
+#if !NO_TPL
+ /// <summary>
+ /// Projects each element of an observable sequence to a task, invokes the result selector for the source element and the task result, and merges the results into one observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TTaskResult">The type of the results produced by the projected intermediate tasks.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, obtained by using the selector to combine source sequence elements with their corresponding intermediate task results.</typeparam>
+ /// <param name="source">An observable sequence of elements to project.</param>
+ /// <param name="taskSelector">A transform function to apply to each element.</param>
+ /// <param name="resultSelector">A transform function to apply to each element of the intermediate sequence.</param>
+ /// <returns>An observable sequence whose elements are the result of obtaining a task for each element of the input sequence and then mapping the task's result and its corresponding source element to a result element.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="taskSelector"/> or <paramref name="resultSelector"/> is null.</exception>
+ /// <remarks>This overload supports using LINQ query comprehension syntax in C# and Visual Basic to compose observable sequences and tasks, without requiring manual conversion of the tasks to observable sequences using <see cref="TaskObservableExtensions.ToObservable&lt;TResult&gt;"/>.</remarks>
+ public static IObservable<TResult> SelectMany<TSource, TTaskResult, TResult>(this IObservable<TSource> source, Func<TSource, Task<TTaskResult>> taskSelector, Func<TSource, TTaskResult, TResult> resultSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (taskSelector == null)
+ throw new ArgumentNullException("taskSelector");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.SelectMany<TSource, TTaskResult, TResult>(source, taskSelector, resultSelector);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence to a task with cancellation support, invokes the result selector for the source element and the task result, and merges the results into one observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TTaskResult">The type of the results produced by the projected intermediate tasks.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, obtained by using the selector to combine source sequence elements with their corresponding intermediate task results.</typeparam>
+ /// <param name="source">An observable sequence of elements to project.</param>
+ /// <param name="taskSelector">A transform function to apply to each element.</param>
+ /// <param name="resultSelector">A transform function to apply to each element of the intermediate sequence.</param>
+ /// <returns>An observable sequence whose elements are the result of obtaining a task for each element of the input sequence and then mapping the task's result and its corresponding source element to a result element.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="taskSelector"/> or <paramref name="resultSelector"/> is null.</exception>
+ /// <remarks>This overload supports using LINQ query comprehension syntax in C# and Visual Basic to compose observable sequences and tasks, without requiring manual conversion of the tasks to observable sequences using <see cref="TaskObservableExtensions.ToObservable&lt;TResult&gt;"/>.</remarks>
+ public static IObservable<TResult> SelectMany<TSource, TTaskResult, TResult>(this IObservable<TSource> source, Func<TSource, CancellationToken, Task<TTaskResult>> taskSelector, Func<TSource, TTaskResult, TResult> resultSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (taskSelector == null)
+ throw new ArgumentNullException("taskSelector");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.SelectMany<TSource, TTaskResult, TResult>(source, taskSelector, resultSelector);
+ }
+#endif
+
+ /// <summary>
+ /// Projects each notification of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the projected inner sequences and the elements in the merged result sequence.</typeparam>
+ /// <param name="source">An observable sequence of notifications to project.</param>
+ /// <param name="onNext">A transform function to apply to each element.</param>
+ /// <param name="onError">A transform function to apply when an error occurs in the source sequence.</param>
+ /// <param name="onCompleted">A transform function to apply when the end of the source sequence is reached.</param>
+ /// <returns>An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> or <paramref name="onError"/> or <paramref name="onCompleted"/> is null.</exception>
+ public static IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, IObservable<TResult>> onNext, Func<Exception, IObservable<TResult>> onError, Func<IObservable<TResult>> onCompleted)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (onNext == null)
+ throw new ArgumentNullException("onNext");
+ if (onError == null)
+ throw new ArgumentNullException("onError");
+ if (onCompleted == null)
+ throw new ArgumentNullException("onCompleted");
+
+ return s_impl.SelectMany<TSource, TResult>(source, onNext, onError, onCompleted);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence to an enumerable sequence and concatenates the resulting enumerable sequences into one observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the projected inner enumerable sequences and the elements in the merged result sequence.</typeparam>
+ /// <param name="source">An observable sequence of elements to project.</param>
+ /// <param name="selector">A transform function to apply to each element.</param>
+ /// <returns>An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
+ /// <remarks>The projected sequences are enumerated synchonously within the OnNext call of the source sequence. In order to do a concurrent, non-blocking merge, change the selector to return an observable sequence obtained using the <see cref="Observable.ToObservable&lt;TSource&gt;(IEnumerable&lt;TSource&gt;)"/> conversion.</remarks>
+ public static IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (selector == null)
+ throw new ArgumentNullException("selector");
+
+ return s_impl.SelectMany<TSource, TResult>(source, selector);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence to an enumerable sequence, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and merges the results into one observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TCollection">The type of the elements in the projected intermediate enumerable sequences.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the result sequence, obtained by using the selector to combine source sequence elements with their corresponding intermediate sequence elements.</typeparam>
+ /// <param name="source">An observable sequence of elements to project.</param>
+ /// <param name="collectionSelector">A transform function to apply to each element.</param>
+ /// <param name="resultSelector">A transform function to apply to each element of the intermediate sequence.</param>
+ /// <returns>An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="collectionSelector"/> or <paramref name="resultSelector"/> is null.</exception>
+ /// <remarks>The projected sequences are enumerated synchonously within the OnNext call of the source sequence. In order to do a concurrent, non-blocking merge, change the selector to return an observable sequence obtained using the <see cref="Observable.ToObservable&lt;TSource&gt;(IEnumerable&lt;TSource&gt;)"/> conversion.</remarks>
+ public static IObservable<TResult> SelectMany<TSource, TCollection, TResult>(this IObservable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (collectionSelector == null)
+ throw new ArgumentNullException("collectionSelector");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+
+ return s_impl.SelectMany<TSource, TCollection, TResult>(source, collectionSelector, resultSelector);
+ }
+
+ #endregion
+
+ #region + Skip +
+
+ /// <summary>
+ /// Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">The sequence to take elements from.</param>
+ /// <param name="count">The number of elements to skip before returning the remaining elements.</param>
+ /// <returns>An observable sequence that contains the elements that occur after the specified index in the input sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero.</exception>
+ public static IObservable<TSource> Skip<TSource>(this IObservable<TSource> source, int count)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ return s_impl.Skip<TSource>(source, count);
+ }
+
+ #endregion
+
+ #region + SkipWhile +
+
+ /// <summary>
+ /// Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to return elements from.</param>
+ /// <param name="predicate">A function to test each element for a condition.</param>
+ /// <returns>An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ public static IObservable<TSource> SkipWhile<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.SkipWhile<TSource>(source, predicate);
+ }
+
+ /// <summary>
+ /// Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
+ /// The element's index is used in the logic of the predicate function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence to return elements from.</param>
+ /// <param name="predicate">A function to test each element for a condition; the second parameter of the function represents the index of the source element.</param>
+ /// <returns>An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ public static IObservable<TSource> SkipWhile<TSource>(this IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.SkipWhile<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + Take +
+
+ /// <summary>
+ /// Returns a specified number of contiguous elements from the start of an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">The sequence to take elements from.</param>
+ /// <param name="count">The number of elements to return.</param>
+ /// <returns>An observable sequence that contains the specified number of elements from the start of the input sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero.</exception>
+ public static IObservable<TSource> Take<TSource>(this IObservable<TSource> source, int count)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ return s_impl.Take<TSource>(source, count);
+ }
+
+ /// <summary>
+ /// Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of Take(0).
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">The sequence to take elements from.</param>
+ /// <param name="count">The number of elements to return.</param>
+ /// <param name="scheduler">Scheduler used to produce an OnCompleted message in case <paramref name="count">count</paramref> is set to 0.</param>
+ /// <returns>An observable sequence that contains the specified number of elements from the start of the input sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero.</exception>
+ public static IObservable<TSource> Take<TSource>(this IObservable<TSource> source, int count, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Take<TSource>(source, count, scheduler);
+ }
+
+ #endregion
+
+ #region + TakeWhile +
+
+ /// <summary>
+ /// Returns elements from an observable sequence as long as a specified condition is true.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence to return elements from.</param>
+ /// <param name="predicate">A function to test each element for a condition.</param>
+ /// <returns>An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ public static IObservable<TSource> TakeWhile<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.TakeWhile<TSource>(source, predicate);
+ }
+
+ /// <summary>
+ /// Returns elements from an observable sequence as long as a specified condition is true.
+ /// The element's index is used in the logic of the predicate function.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">A sequence to return elements from.</param>
+ /// <param name="predicate">A function to test each element for a condition; the second parameter of the function represents the index of the source element.</param>
+ /// <returns>An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ public static IObservable<TSource> TakeWhile<TSource>(this IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.TakeWhile<TSource>(source, predicate);
+ }
+
+ #endregion
+
+ #region + Where +
+
+ /// <summary>
+ /// Filters the elements of an observable sequence based on a predicate.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence whose elements to filter.</param>
+ /// <param name="predicate">A function to test each source element for a condition.</param>
+ /// <returns>An observable sequence that contains elements from the input sequence that satisfy the condition.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ public static IObservable<TSource> Where<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.Where<TSource>(source, predicate);
+ }
+
+ /// <summary>
+ /// Filters the elements of an observable sequence based on a predicate by incorporating the element's index.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">An observable sequence whose elements to filter.</param>
+ /// <param name="predicate">A function to test each source element for a conditio; the second parameter of the function represents the index of the source element.</param>
+ /// <returns>An observable sequence that contains elements from the input sequence that satisfy the condition.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
+ public static IObservable<TSource> Where<TSource>(this IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (predicate == null)
+ throw new ArgumentNullException("predicate");
+
+ return s_impl.Where<TSource>(source, predicate);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Time.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Time.cs
new file mode 100644
index 0000000..3736416
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Time.cs
@@ -0,0 +1,1985 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+
+namespace System.Reactive.Linq
+{
+ public static partial class Observable
+ {
+ #region + Buffer +
+
+ #region TimeSpan only
+
+ /// <summary>
+ /// Projects each element of an observable sequence into consecutive non-overlapping buffers which are produced based on timing information.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="timeSpan">Length of each buffer.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create buffers as fast as it can.
+ /// Because all source sequence elements end up in one of the buffers, some buffers won't have a zero time span. This is a side-effect of the asynchrony introduced
+ /// by the scheduler, where the action to close the current buffer and to create a new buffer may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, TimeSpan timeSpan)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+
+ return s_impl.Buffer<TSource>(source, timeSpan);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into consecutive non-overlapping buffers which are produced based on timing information, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="timeSpan">Length of each buffer.</param>
+ /// <param name="scheduler">Scheduler to run buffering timers on.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create buffers as fast as it can.
+ /// Because all source sequence elements end up in one of the buffers, some buffers won't have a zero time span. This is a side-effect of the asynchrony introduced
+ /// by the scheduler, where the action to close the current buffer and to create a new buffer may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Buffer<TSource>(source, timeSpan, scheduler);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into zero or more buffers which are produced based on timing information.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="timeSpan">Length of each buffer.</param>
+ /// <param name="timeShift">Interval between creation of consecutive buffers.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> or <paramref name="timeSpan"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create buffers with minimum duration
+ /// length. However, some buffers won't have a zero time span. This is a side-effect of the asynchrony introduced by the scheduler, where the action to close the
+ /// current buffer may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </para>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeShift"/> is not recommended but supported, causing the scheduler to create buffers as fast as it can.
+ /// However, this doesn't mean all buffers will start at the beginning of the source sequence. This is a side-effect of the asynchrony introduced by the scheduler,
+ /// where the action to create a new buffer may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </para>
+ /// </remarks>
+ public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+ if (timeShift < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeShift");
+
+ return s_impl.Buffer<TSource>(source, timeSpan, timeShift);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into zero or more buffers which are produced based on timing information, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="timeSpan">Length of each buffer.</param>
+ /// <param name="timeShift">Interval between creation of consecutive buffers.</param>
+ /// <param name="scheduler">Scheduler to run buffering timers on.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> or <paramref name="timeSpan"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create buffers with minimum duration
+ /// length. However, some buffers won't have a zero time span. This is a side-effect of the asynchrony introduced by the scheduler, where the action to close the
+ /// current buffer may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </para>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeShift"/> is not recommended but supported, causing the scheduler to create buffers as fast as it can.
+ /// However, this doesn't mean all buffers will start at the beginning of the source sequence. This is a side-effect of the asynchrony introduced by the scheduler,
+ /// where the action to create a new buffer may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </para>
+ /// </remarks>
+ public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+ if (timeShift < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeShift");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Buffer<TSource>(source, timeSpan, timeShift, scheduler);
+ }
+
+ #endregion
+
+ #region TimeSpan + int
+
+ /// <summary>
+ /// Projects each element of an observable sequence into a buffer that's sent out when either it's full or a given amount of time has elapsed.
+ /// A useful real-world analogy of this overload is the behavior of a ferry leaving the dock when all seats are taken, or at the scheduled time of departure, whichever event occurs first.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="timeSpan">Maximum time length of a window.</param>
+ /// <param name="count">Maximum element count of a window.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> is less than TimeSpan.Zero. -or- <paramref name="count"/> is less than or equal to zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create buffers as fast as it can.
+ /// Because all source sequence elements end up in one of the buffers, some buffers won't have a zero time span. This is a side-effect of the asynchrony introduced
+ /// by the scheduler, where the action to close the current buffer and to create a new buffer may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, int count)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+ if (count <= 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ return s_impl.Buffer<TSource>(source, timeSpan, count);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into a buffer that's sent out when either it's full or a given amount of time has elapsed, using the specified scheduler to run timers.
+ /// A useful real-world analogy of this overload is the behavior of a ferry leaving the dock when all seats are taken, or at the scheduled time of departure, whichever event occurs first.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce buffers over.</param>
+ /// <param name="timeSpan">Maximum time length of a buffer.</param>
+ /// <param name="count">Maximum element count of a buffer.</param>
+ /// <param name="scheduler">Scheduler to run buffering timers on.</param>
+ /// <returns>An observable sequence of buffers.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> is less than TimeSpan.Zero. -or- <paramref name="count"/> is less than or equal to zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create buffers as fast as it can.
+ /// Because all source sequence elements end up in one of the buffers, some buffers won't have a zero time span. This is a side-effect of the asynchrony introduced
+ /// by the scheduler, where the action to close the current buffer and to create a new buffer may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, int count, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+ if (count <= 0)
+ throw new ArgumentOutOfRangeException("count");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Buffer<TSource>(source, timeSpan, count, scheduler);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region + Delay +
+
+ #region TimeSpan
+
+ /// <summary>
+ /// Time shifts the observable sequence by the specified relative time duration.
+ /// The relative time intervals between the values are preserved.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to delay values for.</param>
+ /// <param name="dueTime">Relative time by which to shift the observable sequence. If this value is equal to TimeSpan.Zero, the scheduler will dispatch observer callbacks as soon as possible.</param>
+ /// <returns>Time-shifted sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// This operator is less efficient than <see cref="Observable.DelaySubscription{T}(IObservable{T}, TimeSpan)">DelaySubscription</see> because it records all notifications and time-delays those. This allows for immediate propagation of errors.
+ /// </para>
+ /// <para>
+ /// Observer callbacks for the resulting sequence will be run on the default scheduler. This effect is similar to using ObserveOn.
+ /// </para>
+ /// <para>
+ /// Exceptions signaled by the source sequence through an OnError callback are forwarded immediately to the result sequence. Any OnNext notifications that were in the queue at the point of the OnError callback will be dropped.
+ /// In order to delay error propagation, consider using the <see cref="Observable.Materialize">Observable.Materialize</see> and <see cref="Observable.Dematerialize">Observable.Dematerialize</see> operators, or use <see cref="Observable.DelaySubscription{T}(IObservable{T}, TimeSpan)">DelaySubscription</see>.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Delay<TSource>(this IObservable<TSource> source, TimeSpan dueTime)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (dueTime < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("dueTime");
+
+ return s_impl.Delay<TSource>(source, dueTime);
+ }
+
+ /// <summary>
+ /// Time shifts the observable sequence by the specified relative time duration, using the specified scheduler to run timers.
+ /// The relative time intervals between the values are preserved.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to delay values for.</param>
+ /// <param name="dueTime">Relative time by which to shift the observable sequence. If this value is equal to TimeSpan.Zero, the scheduler will dispatch observer callbacks as soon as possible.</param>
+ /// <param name="scheduler">Scheduler to run the delay timers on.</param>
+ /// <returns>Time-shifted sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// This operator is less efficient than <see cref="Observable.DelaySubscription{T}(IObservable{T}, TimeSpan, IScheduler)">DelaySubscription</see> because it records all notifications and time-delays those. This allows for immediate propagation of errors.
+ /// </para>
+ /// <para>
+ /// Observer callbacks for the resulting sequence will be run on the specified scheduler. This effect is similar to using ObserveOn.
+ /// </para>
+ /// <para>
+ /// Exceptions signaled by the source sequence through an OnError callback are forwarded immediately to the result sequence. Any OnNext notifications that were in the queue at the point of the OnError callback will be dropped.
+ /// </para>
+ /// <para>
+ /// Exceptions signaled by the source sequence through an OnError callback are forwarded immediately to the result sequence. Any OnNext notifications that were in the queue at the point of the OnError callback will be dropped.
+ /// In order to delay error propagation, consider using the <see cref="Observable.Materialize">Observable.Materialize</see> and <see cref="Observable.Dematerialize">Observable.Dematerialize</see> operators, or use <see cref="Observable.DelaySubscription{T}(IObservable{T}, TimeSpan, IScheduler)">DelaySubscription</see>.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Delay<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (dueTime < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("dueTime");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Delay<TSource>(source, dueTime, scheduler);
+ }
+
+ #endregion
+
+ #region DateTimeOffset
+
+ /// <summary>
+ /// Time shifts the observable sequence to start propagating notifications at the specified absolute time.
+ /// The relative time intervals between the values are preserved.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to delay values for.</param>
+ /// <param name="dueTime">Absolute time used to shift the observable sequence; the relative time shift gets computed upon subscription. If this value is less than or equal to DateTimeOffset.UtcNow, the scheduler will dispatch observer callbacks as soon as possible.</param>
+ /// <returns>Time-shifted sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// This operator is less efficient than <see cref="Observable.DelaySubscription{T}(IObservable{T}, DateTimeOffset)">DelaySubscription</see> because it records all notifications and time-delays those. This allows for immediate propagation of errors.
+ /// </para>
+ /// <para>
+ /// Observer callbacks for the resulting sequence will be run on the default scheduler. This effect is similar to using ObserveOn.
+ /// </para>
+ /// <para>
+ /// Exceptions signaled by the source sequence through an OnError callback are forwarded immediately to the result sequence. Any OnNext notifications that were in the queue at the point of the OnError callback will be dropped.
+ /// In order to delay error propagation, consider using the <see cref="Observable.Materialize">Observable.Materialize</see> and <see cref="Observable.Dematerialize">Observable.Dematerialize</see> operators, or use <see cref="Observable.DelaySubscription{T}(IObservable{T}, DateTimeOffset)">DelaySubscription</see>.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Delay<TSource>(this IObservable<TSource> source, DateTimeOffset dueTime)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Delay<TSource>(source, dueTime);
+ }
+
+ /// <summary>
+ /// Time shifts the observable sequence to start propagating notifications at the specified absolute time, using the specified scheduler to run timers.
+ /// The relative time intervals between the values are preserved.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to delay values for.</param>
+ /// <param name="dueTime">Absolute time used to shift the observable sequence; the relative time shift gets computed upon subscription. If this value is less than or equal to DateTimeOffset.UtcNow, the scheduler will dispatch observer callbacks as soon as possible.</param>
+ /// <param name="scheduler">Scheduler to run the delay timers on.</param>
+ /// <returns>Time-shifted sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// This operator is less efficient than <see cref="Observable.DelaySubscription{T}(IObservable{T}, DateTimeOffset, IScheduler)">DelaySubscription</see> because it records all notifications and time-delays those. This allows for immediate propagation of errors.
+ /// </para>
+ /// <para>
+ /// Observer callbacks for the resulting sequence will be run on the specified scheduler. This effect is similar to using ObserveOn.
+ /// </para>
+ /// <para>
+ /// Exceptions signaled by the source sequence through an OnError callback are forwarded immediately to the result sequence. Any OnNext notifications that were in the queue at the point of the OnError callback will be dropped.
+ /// In order to delay error propagation, consider using the <see cref="Observable.Materialize">Observable.Materialize</see> and <see cref="Observable.Dematerialize">Observable.Dematerialize</see> operators, or use <see cref="Observable.DelaySubscription{T}(IObservable{T}, DateTimeOffset, IScheduler)">DelaySubscription</see>.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Delay<TSource>(this IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Delay<TSource>(source, dueTime, scheduler);
+ }
+
+ #endregion
+
+ #region Duration selector
+
+ /// <summary>
+ /// Time shifts the observable sequence based on a delay selector function for each element.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TDelay">The type of the elements in the delay sequences used to denote the delay duration of each element in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to delay values for.</param>
+ /// <param name="delayDurationSelector">Selector function to retrieve a sequence indicating the delay for each given element.</param>
+ /// <returns>Time-shifted sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="delayDurationSelector"/> is null.</exception>
+ public static IObservable<TSource> Delay<TSource, TDelay>(this IObservable<TSource> source, Func<TSource, IObservable<TDelay>> delayDurationSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (delayDurationSelector == null)
+ throw new ArgumentNullException("delayDurationSelector");
+
+ return s_impl.Delay<TSource, TDelay>(source, delayDurationSelector);
+ }
+
+ /// <summary>
+ /// Time shifts the observable sequence based on a subscription delay and a delay selector function for each element.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TDelay">The type of the elements in the delay sequences used to denote the delay duration of each element in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to delay values for.</param>
+ /// <param name="subscriptionDelay">Sequence indicating the delay for the subscription to the source.</param>
+ /// <param name="delayDurationSelector">Selector function to retrieve a sequence indicating the delay for each given element.</param>
+ /// <returns>Time-shifted sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="subscriptionDelay"/> or <paramref name="delayDurationSelector"/> is null.</exception>
+ public static IObservable<TSource> Delay<TSource, TDelay>(this IObservable<TSource> source, IObservable<TDelay> subscriptionDelay, Func<TSource, IObservable<TDelay>> delayDurationSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (subscriptionDelay == null)
+ throw new ArgumentNullException("subscriptionDelay");
+ if (delayDurationSelector == null)
+ throw new ArgumentNullException("delayDurationSelector");
+
+ return s_impl.Delay<TSource, TDelay>(source, subscriptionDelay, delayDurationSelector);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region + DelaySubscription +
+
+ /// <summary>
+ /// Time shifts the observable sequence by delaying the subscription with the specified relative time duration.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to delay subscription for.</param>
+ /// <param name="dueTime">Relative time shift of the subscription.</param>
+ /// <returns>Time-shifted sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// This operator is more efficient than <see cref="Observable.Delay{T}(IObservable{T}, TimeSpan)">Delay</see> but postpones all side-effects of subscription and affects error propagation timing.
+ /// </para>
+ /// <para>
+ /// The side-effects of subscribing to the source sequence will be run on the default scheduler. Observer callbacks will not be affected.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> DelaySubscription<TSource>(this IObservable<TSource> source, TimeSpan dueTime)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (dueTime < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("dueTime");
+
+ return s_impl.DelaySubscription<TSource>(source, dueTime);
+ }
+
+ /// <summary>
+ /// Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to delay subscription for.</param>
+ /// <param name="dueTime">Relative time shift of the subscription.</param>
+ /// <param name="scheduler">Scheduler to run the subscription delay timer on.</param>
+ /// <returns>Time-shifted sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// This operator is more efficient than <see cref="Observable.Delay{T}(IObservable{T}, TimeSpan, IScheduler)">Delay</see> but postpones all side-effects of subscription and affects error propagation timing.
+ /// </para>
+ /// <para>
+ /// The side-effects of subscribing to the source sequence will be run on the specified scheduler. Observer callbacks will not be affected.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> DelaySubscription<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (dueTime < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("dueTime");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.DelaySubscription<TSource>(source, dueTime, scheduler);
+ }
+
+ /// <summary>
+ /// Time shifts the observable sequence by delaying the subscription to the specified absolute time.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to delay subscription for.</param>
+ /// <param name="dueTime">Absolute time to perform the subscription at.</param>
+ /// <returns>Time-shifted sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// This operator is more efficient than <see cref="Observable.Delay{T}(IObservable{T}, DateTimeOffset)">Delay</see> but postpones all side-effects of subscription and affects error propagation timing.
+ /// </para>
+ /// <para>
+ /// The side-effects of subscribing to the source sequence will be run on the default scheduler. Observer callbacks will not be affected.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> DelaySubscription<TSource>(this IObservable<TSource> source, DateTimeOffset dueTime)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.DelaySubscription<TSource>(source, dueTime);
+ }
+
+ /// <summary>
+ /// Time shifts the observable sequence by delaying the subscription to the specified absolute time, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to delay subscription for.</param>
+ /// <param name="dueTime">Absolute time to perform the subscription at.</param>
+ /// <param name="scheduler">Scheduler to run the subscription delay timer on.</param>
+ /// <returns>Time-shifted sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// <para>
+ /// This operator is more efficient than <see cref="Observable.Delay{T}(IObservable{T}, DateTimeOffset, IScheduler)">Delay</see> but postpones all side-effects of subscription and affects error propagation timing.
+ /// </para>
+ /// <para>
+ /// The side-effects of subscribing to the source sequence will be run on the specified scheduler. Observer callbacks will not be affected.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> DelaySubscription<TSource>(this IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.DelaySubscription<TSource>(source, dueTime, scheduler);
+ }
+
+ #endregion
+
+ #region + Generate +
+
+ /// <summary>
+ /// Generates an observable sequence by running a state-driven and temporal loop producing the sequence's elements.
+ /// </summary>
+ /// <typeparam name="TState">The type of the state used in the generator loop.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="initialState">Initial state.</param>
+ /// <param name="condition">Condition to terminate generation (upon returning false).</param>
+ /// <param name="iterate">Iteration step function.</param>
+ /// <param name="resultSelector">Selector function for results produced in the sequence.</param>
+ /// <param name="timeSelector">Time selector function to control the speed of values being produced each iteration.</param>
+ /// <returns>The generated sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="iterate"/> or <paramref name="resultSelector"/> or <paramref name="timeSelector"/> is null.</exception>
+ public static IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, TimeSpan> timeSelector)
+ {
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+ if (iterate == null)
+ throw new ArgumentNullException("iterate");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+ if (timeSelector == null)
+ throw new ArgumentNullException("timeSelector");
+
+ return s_impl.Generate<TState, TResult>(initialState, condition, iterate, resultSelector, timeSelector);
+ }
+
+ /// <summary>
+ /// Generates an observable sequence by running a state-driven and temporal loop producing the sequence's elements, using the specified scheduler to run timers and to send out observer messages.
+ /// </summary>
+ /// <typeparam name="TState">The type of the state used in the generator loop.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="initialState">Initial state.</param>
+ /// <param name="condition">Condition to terminate generation (upon returning false).</param>
+ /// <param name="iterate">Iteration step function.</param>
+ /// <param name="resultSelector">Selector function for results produced in the sequence.</param>
+ /// <param name="timeSelector">Time selector function to control the speed of values being produced each iteration.</param>
+ /// <param name="scheduler">Scheduler on which to run the generator loop.</param>
+ /// <returns>The generated sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="iterate"/> or <paramref name="resultSelector"/> or <paramref name="timeSelector"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, TimeSpan> timeSelector, IScheduler scheduler)
+ {
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+ if (iterate == null)
+ throw new ArgumentNullException("iterate");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+ if (timeSelector == null)
+ throw new ArgumentNullException("timeSelector");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Generate<TState, TResult>(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
+ }
+
+ /// <summary>
+ /// Generates an observable sequence by running a state-driven and temporal loop producing the sequence's elements.
+ /// </summary>
+ /// <typeparam name="TState">The type of the state used in the generator loop.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="initialState">Initial state.</param>
+ /// <param name="condition">Condition to terminate generation (upon returning false).</param>
+ /// <param name="iterate">Iteration step function.</param>
+ /// <param name="resultSelector">Selector function for results produced in the sequence.</param>
+ /// <param name="timeSelector">Time selector function to control the speed of values being produced each iteration.</param>
+ /// <returns>The generated sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="iterate"/> or <paramref name="resultSelector"/> or <paramref name="timeSelector"/> is null.</exception>
+ public static IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, DateTimeOffset> timeSelector)
+ {
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+ if (iterate == null)
+ throw new ArgumentNullException("iterate");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+ if (timeSelector == null)
+ throw new ArgumentNullException("timeSelector");
+
+ return s_impl.Generate<TState, TResult>(initialState, condition, iterate, resultSelector, timeSelector);
+ }
+
+ /// <summary>
+ /// Generates an observable sequence by running a state-driven and temporal loop producing the sequence's elements, using the specified scheduler to run timers and to send out observer messages.
+ /// </summary>
+ /// <typeparam name="TState">The type of the state used in the generator loop.</typeparam>
+ /// <typeparam name="TResult">The type of the elements in the produced sequence.</typeparam>
+ /// <param name="initialState">Initial state.</param>
+ /// <param name="condition">Condition to terminate generation (upon returning false).</param>
+ /// <param name="iterate">Iteration step function.</param>
+ /// <param name="resultSelector">Selector function for results produced in the sequence.</param>
+ /// <param name="timeSelector">Time selector function to control the speed of values being produced each iteration.</param>
+ /// <param name="scheduler">Scheduler on which to run the generator loop.</param>
+ /// <returns>The generated sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="iterate"/> or <paramref name="resultSelector"/> or <paramref name="timeSelector"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, DateTimeOffset> timeSelector, IScheduler scheduler)
+ {
+ if (condition == null)
+ throw new ArgumentNullException("condition");
+ if (iterate == null)
+ throw new ArgumentNullException("iterate");
+ if (resultSelector == null)
+ throw new ArgumentNullException("resultSelector");
+ if (timeSelector == null)
+ throw new ArgumentNullException("timeSelector");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Generate<TState, TResult>(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
+ }
+
+ #endregion
+
+ #region + Interval +
+
+ /// <summary>
+ /// Returns an observable sequence that produces a value after each period.
+ /// </summary>
+ /// <param name="period">Period for producing the values in the resulting sequence. If this value is equal to TimeSpan.Zero, the timer will recur as fast as possible.</param>
+ /// <returns>An observable sequence that produces a value after each period.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// Intervals are measured between the start of subsequent notifications, not between the end of the previous and the start of the next notification.
+ /// If the observer takes longer than the interval period to handle the message, the subsequent notification will be delivered immediately after the
+ /// current one has been handled. In case you need to control the time between the end and the start of consecutive notifications, consider using the
+ /// <see cref="Observable.Generate{TState, TResult}(TState, Func{TState, bool}, Func{TState, TState}, Func{TState, TResult}, Func{TState, TimeSpan})"/>
+ /// operator instead.
+ /// </remarks>
+ public static IObservable<long> Interval(TimeSpan period)
+ {
+ if (period < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("period");
+
+ return s_impl.Interval(period);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that produces a value after each period, using the specified scheduler to run timers and to send out observer messages.
+ /// </summary>
+ /// <param name="period">Period for producing the values in the resulting sequence. If this value is equal to TimeSpan.Zero, the timer will recur as fast as possible.</param>
+ /// <param name="scheduler">Scheduler to run the timer on.</param>
+ /// <returns>An observable sequence that produces a value after each period.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// Intervals are measured between the start of subsequent notifications, not between the end of the previous and the start of the next notification.
+ /// If the observer takes longer than the interval period to handle the message, the subsequent notification will be delivered immediately after the
+ /// current one has been handled. In case you need to control the time between the end and the start of consecutive notifications, consider using the
+ /// <see cref="Observable.Generate{TState, TResult}(TState, Func{TState, bool}, Func{TState, TState}, Func{TState, TResult}, Func{TState, TimeSpan}, IScheduler)"/>
+ /// operator instead.
+ /// </remarks>
+ public static IObservable<long> Interval(TimeSpan period, IScheduler scheduler)
+ {
+ if (period < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("period");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Interval(period, scheduler);
+ }
+
+ #endregion
+
+ #region + Sample +
+
+ /// <summary>
+ /// Samples the observable sequence at each interval.
+ /// Upon each sampling tick, the latest element (if any) in the source sequence during the last sampling interval is sent to the resulting sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to sample.</param>
+ /// <param name="interval">Interval at which to sample. If this value is equal to TimeSpan.Zero, the scheduler will continuously sample the stream.</param>
+ /// <returns>Sampled observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="interval"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="interval"/> doesn't guarantee all source sequence elements will be preserved. This is a side-effect
+ /// of the asynchrony introduced by the scheduler, where the sampling action may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<TSource> Sample<TSource>(this IObservable<TSource> source, TimeSpan interval)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (interval < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("interval");
+
+ return s_impl.Sample<TSource>(source, interval);
+ }
+
+ /// <summary>
+ /// Samples the observable sequence at each interval, using the specified scheduler to run sampling timers.
+ /// Upon each sampling tick, the latest element (if any) in the source sequence during the last sampling interval is sent to the resulting sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to sample.</param>
+ /// <param name="interval">Interval at which to sample. If this value is equal to TimeSpan.Zero, the scheduler will continuously sample the stream.</param>
+ /// <param name="scheduler">Scheduler to run the sampling timer on.</param>
+ /// <returns>Sampled observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="interval"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="interval"/> doesn't guarantee all source sequence elements will be preserved. This is a side-effect
+ /// of the asynchrony introduced by the scheduler, where the sampling action may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<TSource> Sample<TSource>(this IObservable<TSource> source, TimeSpan interval, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (interval < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("interval");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Sample<TSource>(source, interval, scheduler);
+ }
+
+ /// <summary>
+ /// Samples the source observable sequence using a samper observable sequence producing sampling ticks.
+ /// Upon each sampling tick, the latest element (if any) in the source sequence during the last sampling interval is sent to the resulting sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TSample">The type of the elements in the sampling sequence.</typeparam>
+ /// <param name="source">Source sequence to sample.</param>
+ /// <param name="sampler">Sampling tick sequence.</param>
+ /// <returns>Sampled observable sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="sampler"/> is null.</exception>
+ public static IObservable<TSource> Sample<TSource, TSample>(this IObservable<TSource> source, IObservable<TSample> sampler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (sampler == null)
+ throw new ArgumentNullException("sampler");
+
+ return s_impl.Sample<TSource, TSample>(source, sampler);
+ }
+
+ #endregion
+
+ #region + Skip +
+
+ /// <summary>
+ /// Skips elements for the specified duration from the start of the observable source sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to skip elements for.</param>
+ /// <param name="duration">Duration for skipping elements from the start of the sequence.</param>
+ /// <returns>An observable sequence with the elements skipped during the specified duration from the start of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="duration"/> doesn't guarantee no elements will be dropped from the start of the source sequence.
+ /// This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
+ /// may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </para>
+ /// <para>
+ /// Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the <paramref name="duration"/>.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Skip<TSource>(this IObservable<TSource> source, TimeSpan duration)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+
+ return s_impl.Skip<TSource>(source, duration);
+ }
+
+ /// <summary>
+ /// Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to skip elements for.</param>
+ /// <param name="duration">Duration for skipping elements from the start of the sequence.</param>
+ /// <param name="scheduler">Scheduler to run the timer on.</param>
+ /// <returns>An observable sequence with the elements skipped during the specified duration from the start of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="duration"/> doesn't guarantee no elements will be dropped from the start of the source sequence.
+ /// This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
+ /// may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </para>
+ /// <para>
+ /// Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the <paramref name="duration"/>.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Skip<TSource>(this IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Skip<TSource>(source, duration, scheduler);
+ }
+
+ #endregion
+
+ #region + SkipLast +
+
+ /// <summary>
+ /// Skips elements for the specified duration from the end of the observable source sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to skip elements for.</param>
+ /// <param name="duration">Duration for skipping elements from the end of the sequence.</param>
+ /// <returns>An observable sequence with the elements skipped during the specified duration from the end of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a queue with a length enough to store elements received during the initial <paramref name="duration"/> window.
+ /// As more elements are received, elements older than the specified <paramref name="duration"/> are taken from the queue and produced on the
+ /// result sequence. This causes elements to be delayed with <paramref name="duration"/>.
+ /// </remarks>
+ public static IObservable<TSource> SkipLast<TSource>(this IObservable<TSource> source, TimeSpan duration)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+
+ return s_impl.SkipLast<TSource>(source, duration);
+ }
+
+ /// <summary>
+ /// Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to skip elements for.</param>
+ /// <param name="duration">Duration for skipping elements from the end of the sequence.</param>
+ /// <param name="scheduler">Scheduler to run the timer on.</param>
+ /// <returns>An observable sequence with the elements skipped during the specified duration from the end of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a queue with a length enough to store elements received during the initial <paramref name="duration"/> window.
+ /// As more elements are received, elements older than the specified <paramref name="duration"/> are taken from the queue and produced on the
+ /// result sequence. This causes elements to be delayed with <paramref name="duration"/>.
+ /// </remarks>
+ public static IObservable<TSource> SkipLast<TSource>(this IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.SkipLast<TSource>(source, duration, scheduler);
+ }
+
+ #endregion
+
+ #region + SkipUntil +
+
+ /// <summary>
+ /// Skips elements from the observable source sequence until the specified start time.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to skip elements for.</param>
+ /// <param name="startTime">Time to start taking elements from the source sequence. If this value is less than or equal to DateTimeOffset.UtcNow, no elements will be skipped.</param>
+ /// <returns>An observable sequence with the elements skipped until the specified start time.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <remarks>
+ /// Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the <paramref name="startTime"/>.
+ /// </remarks>
+ public static IObservable<TSource> SkipUntil<TSource>(this IObservable<TSource> source, DateTimeOffset startTime)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.SkipUntil<TSource>(source, startTime);
+ }
+
+ /// <summary>
+ /// Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to skip elements for.</param>
+ /// <param name="startTime">Time to start taking elements from the source sequence. If this value is less than or equal to DateTimeOffset.UtcNow, no elements will be skipped.</param>
+ /// <param name="scheduler">Scheduler to run the timer on.</param>
+ /// <returns>An observable sequence with the elements skipped until the specified start time.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the <paramref name="startTime"/>.
+ /// </remarks>
+ public static IObservable<TSource> SkipUntil<TSource>(this IObservable<TSource> source, DateTimeOffset startTime, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.SkipUntil<TSource>(source, startTime, scheduler);
+ }
+
+ #endregion
+
+ #region + Take +
+
+ /// <summary>
+ /// Takes elements for the specified duration from the start of the observable source sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to take elements from.</param>
+ /// <param name="duration">Duration for taking elements from the start of the sequence.</param>
+ /// <returns>An observable sequence with the elements taken during the specified duration from the start of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="duration"/> doesn't guarantee an empty sequence will be returned. This is a side-effect
+ /// of the asynchrony introduced by the scheduler, where the action that stops forwarding callbacks from the source sequence may not execute
+ /// immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<TSource> Take<TSource>(this IObservable<TSource> source, TimeSpan duration)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+
+ return s_impl.Take<TSource>(source, duration);
+ }
+
+ /// <summary>
+ /// Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to take elements from.</param>
+ /// <param name="duration">Duration for taking elements from the start of the sequence.</param>
+ /// <param name="scheduler">Scheduler to run the timer on.</param>
+ /// <returns>An observable sequence with the elements taken during the specified duration from the start of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="duration"/> doesn't guarantee an empty sequence will be returned. This is a side-effect
+ /// of the asynchrony introduced by the scheduler, where the action that stops forwarding callbacks from the source sequence may not execute
+ /// immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<TSource> Take<TSource>(this IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Take<TSource>(source, duration, scheduler);
+ }
+
+ #endregion
+
+ #region + TakeLast +
+
+ /// <summary>
+ /// Returns elements within the specified duration from the end of the observable source sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to take elements from.</param>
+ /// <param name="duration">Duration for taking elements from the end of the sequence.</param>
+ /// <returns>An observable sequence with the elements taken during the specified duration from the end of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a buffer with a length enough to store elements for any <paramref name="duration"/> window during the lifetime of
+ /// the source sequence. Upon completion of the source sequence, this buffer is drained on the result sequence. This causes the result elements
+ /// to be delayed with <paramref name="duration"/>.
+ /// </remarks>
+ public static IObservable<TSource> TakeLast<TSource>(this IObservable<TSource> source, TimeSpan duration)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+
+ return s_impl.TakeLast<TSource>(source, duration);
+ }
+
+ /// <summary>
+ /// Returns elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to take elements from.</param>
+ /// <param name="duration">Duration for taking elements from the end of the sequence.</param>
+ /// <param name="scheduler">Scheduler to run the timer on.</param>
+ /// <returns>An observable sequence with the elements taken during the specified duration from the end of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a buffer with a length enough to store elements for any <paramref name="duration"/> window during the lifetime of
+ /// the source sequence. Upon completion of the source sequence, this buffer is drained on the result sequence. This causes the result elements
+ /// to be delayed with <paramref name="duration"/>.
+ /// </remarks>
+ public static IObservable<TSource> TakeLast<TSource>(this IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.TakeLast<TSource>(source, duration, scheduler);
+ }
+
+ /// <summary>
+ /// Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to take elements from.</param>
+ /// <param name="duration">Duration for taking elements from the end of the sequence.</param>
+ /// <param name="timerScheduler">Scheduler to run the timer on.</param>
+ /// <param name="loopScheduler">Scheduler to drain the collected elements.</param>
+ /// <returns>An observable sequence with the elements taken during the specified duration from the end of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="timerScheduler"/> or <paramref name="loopScheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a buffer with a length enough to store elements for any <paramref name="duration"/> window during the lifetime of
+ /// the source sequence. Upon completion of the source sequence, this buffer is drained on the result sequence. This causes the result elements
+ /// to be delayed with <paramref name="duration"/>.
+ /// </remarks>
+ public static IObservable<TSource> TakeLast<TSource>(this IObservable<TSource> source, TimeSpan duration, IScheduler timerScheduler, IScheduler loopScheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+ if (timerScheduler == null)
+ throw new ArgumentNullException("timerScheduler");
+ if (loopScheduler == null)
+ throw new ArgumentNullException("loopScheduler");
+
+ return s_impl.TakeLast<TSource>(source, duration, timerScheduler, loopScheduler);
+ }
+
+ #endregion
+
+ #region + TakeLastBuffer +
+
+ /// <summary>
+ /// Returns a list with the elements within the specified duration from the end of the observable source sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to take elements from.</param>
+ /// <param name="duration">Duration for taking elements from the end of the sequence.</param>
+ /// <returns>An observable sequence containing a single list with the elements taken during the specified duration from the end of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a buffer with a length enough to store elements for any <paramref name="duration"/> window during the lifetime of
+ /// the source sequence. Upon completion of the source sequence, this buffer is produced on the result sequence.
+ /// </remarks>
+ public static IObservable<IList<TSource>> TakeLastBuffer<TSource>(this IObservable<TSource> source, TimeSpan duration)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+
+ return s_impl.TakeLastBuffer<TSource>(source, duration);
+ }
+
+ /// <summary>
+ /// Returns a list with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to take elements from.</param>
+ /// <param name="duration">Duration for taking elements from the end of the sequence.</param>
+ /// <param name="scheduler">Scheduler to run the timer on.</param>
+ /// <returns>An observable sequence containing a single list with the elements taken during the specified duration from the end of the source sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// This operator accumulates a buffer with a length enough to store elements for any <paramref name="duration"/> window during the lifetime of
+ /// the source sequence. Upon completion of the source sequence, this buffer is produced on the result sequence.
+ /// </remarks>
+ public static IObservable<IList<TSource>> TakeLastBuffer<TSource>(this IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (duration < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("duration");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.TakeLastBuffer<TSource>(source, duration, scheduler);
+ }
+
+ #endregion
+
+ #region + TakeUntil +
+
+ /// <summary>
+ /// Takes elements for the specified duration until the specified end time.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to take elements from.</param>
+ /// <param name="endTime">Time to stop taking elements from the source sequence. If this value is less than or equal to DateTimeOffset.UtcNow, the result stream will complete immediately.</param>
+ /// <returns>An observable sequence with the elements taken until the specified end time.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<TSource> TakeUntil<TSource>(this IObservable<TSource> source, DateTimeOffset endTime)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.TakeUntil<TSource>(source, endTime);
+ }
+
+ /// <summary>
+ /// Takes elements for the specified duration until the specified end time, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to take elements from.</param>
+ /// <param name="endTime">Time to stop taking elements from the source sequence. If this value is less than or equal to DateTimeOffset.UtcNow, the result stream will complete immediately.</param>
+ /// <param name="scheduler">Scheduler to run the timer on.</param>
+ /// <returns>An observable sequence with the elements taken until the specified end time.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<TSource> TakeUntil<TSource>(this IObservable<TSource> source, DateTimeOffset endTime, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.TakeUntil<TSource>(source, endTime, scheduler);
+ }
+
+ #endregion
+
+ #region + Throttle +
+
+ /// <summary>
+ /// Ignores elements from an observable sequence which are followed by another element within a specified relative time duration.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to throttle.</param>
+ /// <param name="dueTime">Throttling duration for each element.</param>
+ /// <returns>The throttled sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// This operator throttles the source sequence by holding on to each element for the duration specified in <paramref name="dueTime"/>. If another
+ /// element is produced within this time window, the element is dropped and a new timer is started for the current element, repeating this whole
+ /// process. For streams that never have gaps larger than or equal to <paramref name="dueTime"/> between elements, the resulting stream won't
+ /// produce any elements. In order to reduce the volume of a stream whilst guaranteeing the periodic production of elements, consider using the
+ /// Observable.Sample set of operators.
+ /// </para>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="dueTime"/> is not recommended but supported, causing throttling timers to be scheduled
+ /// that are due immediately. However, this doesn't guarantee all elements will be retained in the result sequence. This is a side-effect of the
+ /// asynchrony introduced by the scheduler, where the action to forward the current element may not execute immediately, despite the TimeSpan.Zero
+ /// due time. In such cases, the next element may arrive before the scheduler gets a chance to run the throttling action.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Throttle<TSource>(this IObservable<TSource> source, TimeSpan dueTime)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (dueTime < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("dueTime");
+
+ return s_impl.Throttle<TSource>(source, dueTime);
+ }
+
+ /// <summary>
+ /// Ignores elements from an observable sequence which are followed by another element within a specified relative time duration, using the specified scheduler to run throttling timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to throttle.</param>
+ /// <param name="dueTime">Throttling duration for each element.</param>
+ /// <param name="scheduler">Scheduler to run the throttle timers on.</param>
+ /// <returns>The throttled sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// This operator throttles the source sequence by holding on to each element for the duration specified in <paramref name="dueTime"/>. If another
+ /// element is produced within this time window, the element is dropped and a new timer is started for the current element, repeating this whole
+ /// process. For streams that never have gaps larger than or equal to <paramref name="dueTime"/> between elements, the resulting stream won't
+ /// produce any elements. In order to reduce the volume of a stream whilst guaranteeing the periodic production of elements, consider using the
+ /// Observable.Sample set of operators.
+ /// </para>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="dueTime"/> is not recommended but supported, causing throttling timers to be scheduled
+ /// that are due immediately. However, this doesn't guarantee all elements will be retained in the result sequence. This is a side-effect of the
+ /// asynchrony introduced by the scheduler, where the action to forward the current element may not execute immediately, despite the TimeSpan.Zero
+ /// due time. In such cases, the next element may arrive before the scheduler gets a chance to run the throttling action.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Throttle<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (dueTime < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("dueTime");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Throttle<TSource>(source, dueTime, scheduler);
+ }
+
+ /// <summary>
+ /// Ignores elements from an observable sequence which are followed by another value within a computed throttle duration.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TThrottle">The type of the elements in the throttle sequences selected for each element in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to throttle.</param>
+ /// <param name="throttleDurationSelector">Selector function to retrieve a sequence indicating the throttle duration for each given element.</param>
+ /// <returns>The throttled sequence.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="throttleDurationSelector"/> is null.</exception>
+ /// <remarks>
+ /// This operator throttles the source sequence by holding on to each element for the duration denoted by <paramref name="throttleDurationSelector"/>.
+ /// If another element is produced within this time window, the element is dropped and a new timer is started for the current element, repeating this
+ /// whole process. For streams where the duration computed by applying the <paramref name="throttleDurationSelector"/> to each element overlaps with
+ /// the occurrence of the successor element, the resulting stream won't produce any elements. In order to reduce the volume of a stream whilst
+ /// guaranteeing the periodic production of elements, consider using the Observable.Sample set of operators.
+ /// </remarks>
+ public static IObservable<TSource> Throttle<TSource, TThrottle>(this IObservable<TSource> source, Func<TSource, IObservable<TThrottle>> throttleDurationSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (throttleDurationSelector == null)
+ throw new ArgumentNullException("throttleDurationSelector");
+
+ return s_impl.Throttle<TSource, TThrottle>(source, throttleDurationSelector);
+ }
+
+ #endregion
+
+ #region + TimeInterval +
+
+ /// <summary>
+ /// Records the time interval between consecutive elements in an observable sequence.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to record time intervals for.</param>
+ /// <returns>An observable sequence with time interval information on elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<System.Reactive.TimeInterval<TSource>> TimeInterval<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.TimeInterval<TSource>(source);
+ }
+
+ /// <summary>
+ /// Records the time interval between consecutive elements in an observable sequence, using the specified scheduler to compute time intervals.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to record time intervals for.</param>
+ /// <param name="scheduler">Scheduler used to compute time intervals.</param>
+ /// <returns>An observable sequence with time interval information on elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<System.Reactive.TimeInterval<TSource>> TimeInterval<TSource>(this IObservable<TSource> source, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.TimeInterval<TSource>(source, scheduler);
+ }
+
+ #endregion
+
+ #region + Timeout +
+
+ #region TimeSpan
+
+ /// <summary>
+ /// Applies a timeout policy for each element in the observable sequence.
+ /// If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutException is propagated to the observer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="dueTime">Maximum duration between values before a timeout occurs.</param>
+ /// <returns>The source sequence with a TimeoutException in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
+ /// <exception cref="TimeoutException">(Asynchronous) If no element is produced within <paramref name="dueTime"/> from the previous element.</exception>
+ /// <remarks>
+ /// <para>
+ /// In case you only want to timeout on the first element, consider using the <see cref="Observable.Amb{TSource}(IObservable{TSource}, IObservable{TSource})"/>
+ /// operator applied to the source sequence and a delayed <see cref="Observable.Throw{TResult}(Exception)"/> sequence. Alternatively, the general-purpose overload
+ /// of Timeout, <see cref="Timeout{TSource, TTimeout}(IObservable{TSource}, IObservable{TTimeout}, Func{TSource, IObservable{TTimeout}})"/> can be used.
+ /// </para>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="dueTime"/> is not recommended but supported, causing timeout timers to be scheduled that are due
+ /// immediately. However, this doesn't guarantee a timeout will occur, even for the first element. This is a side-effect of the asynchrony introduced by the
+ /// scheduler, where the action to propagate a timeout may not execute immediately, despite the TimeSpan.Zero due time. In such cases, the next element may
+ /// arrive before the scheduler gets a chance to run the timeout action.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Timeout<TSource>(this IObservable<TSource> source, TimeSpan dueTime)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (dueTime < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("dueTime");
+
+ return s_impl.Timeout<TSource>(source, dueTime);
+ }
+
+ /// <summary>
+ /// Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers.
+ /// If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutException is propagated to the observer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="dueTime">Maximum duration between values before a timeout occurs.</param>
+ /// <param name="scheduler">Scheduler to run the timeout timers on.</param>
+ /// <returns>The source sequence with a TimeoutException in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
+ /// <exception cref="TimeoutException">(Asynchronous) If no element is produced within <paramref name="dueTime"/> from the previous element.</exception>
+ /// <remarks>
+ /// <para>
+ /// In case you only want to timeout on the first element, consider using the <see cref="Observable.Amb{TSource}(IObservable{TSource}, IObservable{TSource})"/>
+ /// operator applied to the source sequence and a delayed <see cref="Observable.Throw{TResult}(Exception)"/> sequence. Alternatively, the general-purpose overload
+ /// of Timeout, <see cref="Timeout{TSource, TTimeout}(IObservable{TSource}, IObservable{TTimeout}, Func{TSource, IObservable{TTimeout}})"/> can be used.
+ /// </para>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="dueTime"/> is not recommended but supported, causing timeout timers to be scheduled that are due
+ /// immediately. However, this doesn't guarantee a timeout will occur, even for the first element. This is a side-effect of the asynchrony introduced by the
+ /// scheduler, where the action to propagate a timeout may not execute immediately, despite the TimeSpan.Zero due time. In such cases, the next element may
+ /// arrive before the scheduler gets a chance to run the timeout action.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Timeout<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (dueTime < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("dueTime");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Timeout<TSource>(source, dueTime, scheduler);
+ }
+
+ /// <summary>
+ /// Applies a timeout policy for each element in the observable sequence.
+ /// If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence and the other sequence used upon a timeout.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="dueTime">Maximum duration between values before a timeout occurs.</param>
+ /// <param name="other">Sequence to return in case of a timeout.</param>
+ /// <returns>The source sequence switching to the other sequence in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="other"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// In case you only want to timeout on the first element, consider using the <see cref="Observable.Amb{TSource}(IObservable{TSource}, IObservable{TSource})"/>
+ /// operator applied to the source sequence and a delayed <see cref="Observable.Throw{TResult}(Exception)"/> sequence. Alternatively, the general-purpose overload
+ /// of Timeout, <see cref="Timeout{TSource, TTimeout}(IObservable{TSource}, IObservable{TTimeout}, Func{TSource, IObservable{TTimeout}})"/> can be used.
+ /// </para>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="dueTime"/> is not recommended but supported, causing timeout timers to be scheduled that are due
+ /// immediately. However, this doesn't guarantee a timeout will occur, even for the first element. This is a side-effect of the asynchrony introduced by the
+ /// scheduler, where the action to propagate a timeout may not execute immediately, despite the TimeSpan.Zero due time. In such cases, the next element may
+ /// arrive before the scheduler gets a chance to run the timeout action.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Timeout<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IObservable<TSource> other)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (dueTime < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("dueTime");
+ if (other == null)
+ throw new ArgumentNullException("other");
+
+ return s_impl.Timeout<TSource>(source, dueTime, other);
+ }
+
+ /// <summary>
+ /// Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers.
+ /// If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence and the other sequence used upon a timeout.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="dueTime">Maximum duration between values before a timeout occurs.</param>
+ /// <param name="other">Sequence to return in case of a timeout.</param>
+ /// <param name="scheduler">Scheduler to run the timeout timers on.</param>
+ /// <returns>The source sequence switching to the other sequence in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="other"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// In case you only want to timeout on the first element, consider using the <see cref="Observable.Amb{TSource}(IObservable{TSource}, IObservable{TSource})"/>
+ /// operator applied to the source sequence and a delayed <see cref="Observable.Throw{TResult}(Exception)"/> sequence. Alternatively, the general-purpose overload
+ /// of Timeout, <see cref="Timeout{TSource, TTimeout}(IObservable{TSource}, IObservable{TTimeout}, Func{TSource, IObservable{TTimeout}})"/> can be used.
+ /// </para>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="dueTime"/> is not recommended but supported, causing timeout timers to be scheduled that are due
+ /// immediately. However, this doesn't guarantee a timeout will occur, even for the first element. This is a side-effect of the asynchrony introduced by the
+ /// scheduler, where the action to propagate a timeout may not execute immediately, despite the TimeSpan.Zero due time. In such cases, the next element may
+ /// arrive before the scheduler gets a chance to run the timeout action.
+ /// </para>
+ /// </remarks>
+ public static IObservable<TSource> Timeout<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IObservable<TSource> other, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (dueTime < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("dueTime");
+ if (other == null)
+ throw new ArgumentNullException("other");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Timeout<TSource>(source, dueTime, other, scheduler);
+ }
+
+ #endregion
+
+ #region DateTimeOffset
+
+ /// <summary>
+ /// Applies a timeout policy to the observable sequence based on an absolute time.
+ /// If the sequence doesn't terminate before the specified absolute due time, a TimeoutException is propagated to the observer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="dueTime">Time when a timeout occurs. If this value is less than or equal to DateTimeOffset.UtcNow, the timeout occurs immediately.</param>
+ /// <returns>The source sequence with a TimeoutException in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="TimeoutException">(Asynchronous) If the sequence hasn't terminated before <paramref name="dueTime"/>.</exception>
+ /// <remarks>
+ /// In case you only want to timeout on the first element, consider using the <see cref="Observable.Amb{TSource}(IObservable{TSource}, IObservable{TSource})"/>
+ /// operator applied to the source sequence and a delayed <see cref="Observable.Throw{TResult}(Exception)"/> sequence. Alternatively, the general-purpose overload
+ /// of Timeout, <see cref="Timeout{TSource, TTimeout}(IObservable{TSource}, IObservable{TTimeout}, Func{TSource, IObservable{TTimeout}})"/> can be used.
+ /// </remarks>
+ public static IObservable<TSource> Timeout<TSource>(this IObservable<TSource> source, DateTimeOffset dueTime)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Timeout<TSource>(source, dueTime);
+ }
+
+ /// <summary>
+ /// Applies a timeout policy to the observable sequence based on an absolute time, using the specified scheduler to run timeout timers.
+ /// If the sequence doesn't terminate before the specified absolute due time, a TimeoutException is propagated to the observer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="dueTime">Time when a timeout occurs. If this value is less than or equal to DateTimeOffset.UtcNow, the timeout occurs immediately.</param>
+ /// <param name="scheduler">Scheduler to run the timeout timers on.</param>
+ /// <returns>The source sequence with a TimeoutException in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="TimeoutException">(Asynchronous) If the sequence hasn't terminated before <paramref name="dueTime"/>.</exception>
+ /// <remarks>
+ /// In case you only want to timeout on the first element, consider using the <see cref="Observable.Amb{TSource}(IObservable{TSource}, IObservable{TSource})"/>
+ /// operator applied to the source sequence and a delayed <see cref="Observable.Throw{TResult}(Exception)"/> sequence. Alternatively, the general-purpose overload
+ /// of Timeout, <see cref="Timeout{TSource, TTimeout}(IObservable{TSource}, IObservable{TTimeout}, Func{TSource, IObservable{TTimeout}})"/> can be used.
+ /// </remarks>
+ public static IObservable<TSource> Timeout<TSource>(this IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Timeout<TSource>(source, dueTime, scheduler);
+ }
+
+ /// <summary>
+ /// Applies a timeout policy to the observable sequence based on an absolute time.
+ /// If the sequence doesn't terminate before the specified absolute due time, the other observable sequence is used to produce future messages from that point on.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence and the other sequence used upon a timeout.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="dueTime">Time when a timeout occurs. If this value is less than or equal to DateTimeOffset.UtcNow, the timeout occurs immediately.</param>
+ /// <param name="other">Sequence to return in case of a timeout.</param>
+ /// <returns>The source sequence switching to the other sequence in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="other"/> is null.</exception>
+ /// <remarks>
+ /// In case you only want to timeout on the first element, consider using the <see cref="Observable.Amb{TSource}(IObservable{TSource}, IObservable{TSource})"/>
+ /// operator applied to the source sequence and a delayed <see cref="Observable.Throw{TResult}(Exception)"/> sequence. Alternatively, the general-purpose overload
+ /// of Timeout, <see cref="Timeout{TSource, TTimeout}(IObservable{TSource}, IObservable{TTimeout}, Func{TSource, IObservable{TTimeout}})"/> can be used.
+ /// </remarks>
+ public static IObservable<TSource> Timeout<TSource>(this IObservable<TSource> source, DateTimeOffset dueTime, IObservable<TSource> other)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (other == null)
+ throw new ArgumentNullException("other");
+
+ return s_impl.Timeout<TSource>(source, dueTime, other);
+ }
+
+ /// <summary>
+ /// Applies a timeout policy to the observable sequence based on an absolute time, using the specified scheduler to run timeout timers.
+ /// If the sequence doesn't terminate before the specified absolute due time, the other observable sequence is used to produce future messages from that point on.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence and the other sequence used upon a timeout.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="dueTime">Time when a timeout occurs. If this value is less than or equal to DateTimeOffset.UtcNow, the timeout occurs immediately.</param>
+ /// <param name="other">Sequence to return in case of a timeout.</param>
+ /// <param name="scheduler">Scheduler to run the timeout timers on.</param>
+ /// <returns>The source sequence switching to the other sequence in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="other"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <remarks>
+ /// In case you only want to timeout on the first element, consider using the <see cref="Observable.Amb{TSource}(IObservable{TSource}, IObservable{TSource})"/>
+ /// operator applied to the source sequence and a delayed <see cref="Observable.Throw{TResult}(Exception)"/> sequence. Alternatively, the general-purpose overload
+ /// of Timeout, <see cref="Timeout{TSource, TTimeout}(IObservable{TSource}, IObservable{TTimeout}, Func{TSource, IObservable{TTimeout}})"/> can be used.
+ /// </remarks>
+ public static IObservable<TSource> Timeout<TSource>(this IObservable<TSource> source, DateTimeOffset dueTime, IObservable<TSource> other, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+ if (other == null)
+ throw new ArgumentNullException("other");
+
+ return s_impl.Timeout<TSource>(source, dueTime, other, scheduler);
+ }
+
+ #endregion
+
+ #region Duration selector
+
+ /// <summary>
+ /// Applies a timeout policy to the observable sequence based on a timeout duration computed for each element.
+ /// If the next element isn't received within the computed duration starting from its predecessor, a TimeoutException is propagated to the observer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TTimeout">The type of the elements in the timeout sequences used to indicate the timeout duration for each element in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="timeoutDurationSelector">Selector to retrieve an observable sequence that represents the timeout between the current element and the next element.</param>
+ /// <returns>The source sequence with a TimeoutException in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="timeoutDurationSelector"/> is null.</exception>
+ public static IObservable<TSource> Timeout<TSource, TTimeout>(this IObservable<TSource> source, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeoutDurationSelector == null)
+ throw new ArgumentNullException("timeoutDurationSelector");
+
+ return s_impl.Timeout<TSource, TTimeout>(source, timeoutDurationSelector);
+ }
+
+ /// <summary>
+ /// Applies a timeout policy to the observable sequence based on a timeout duration computed for each element.
+ /// If the next element isn't received within the computed duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence and the other sequence used upon a timeout.</typeparam>
+ /// <typeparam name="TTimeout">The type of the elements in the timeout sequences used to indicate the timeout duration for each element in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="timeoutDurationSelector">Selector to retrieve an observable sequence that represents the timeout between the current element and the next element.</param>
+ /// <param name="other">Sequence to return in case of a timeout.</param>
+ /// <returns>The source sequence switching to the other sequence in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="timeoutDurationSelector"/> or <paramref name="other"/> is null.</exception>
+ public static IObservable<TSource> Timeout<TSource, TTimeout>(this IObservable<TSource> source, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector, IObservable<TSource> other)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeoutDurationSelector == null)
+ throw new ArgumentNullException("timeoutDurationSelector");
+ if (other == null)
+ throw new ArgumentNullException("other");
+
+ return s_impl.Timeout<TSource, TTimeout>(source, timeoutDurationSelector, other);
+ }
+
+ /// <summary>
+ /// Applies a timeout policy to the observable sequence based on an initial timeout duration for the first element, and a timeout duration computed for each subsequent element.
+ /// If the next element isn't received within the computed duration starting from its predecessor, a TimeoutException is propagated to the observer.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <typeparam name="TTimeout">The type of the elements in the timeout sequences used to indicate the timeout duration for each element in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="firstTimeout">Observable sequence that represents the timeout for the first element.</param>
+ /// <param name="timeoutDurationSelector">Selector to retrieve an observable sequence that represents the timeout between the current element and the next element.</param>
+ /// <returns>The source sequence with a TimeoutException in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="firstTimeout"/> or <paramref name="timeoutDurationSelector"/> is null.</exception>
+ public static IObservable<TSource> Timeout<TSource, TTimeout>(this IObservable<TSource> source, IObservable<TTimeout> firstTimeout, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (firstTimeout == null)
+ throw new ArgumentNullException("firstTimeout");
+ if (timeoutDurationSelector == null)
+ throw new ArgumentNullException("timeoutDurationSelector");
+
+ return s_impl.Timeout<TSource, TTimeout>(source, firstTimeout, timeoutDurationSelector);
+ }
+
+ /// <summary>
+ /// Applies a timeout policy to the observable sequence based on an initial timeout duration for the first element, and a timeout duration computed for each subsequent element.
+ /// If the next element isn't received within the computed duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence and the other sequence used upon a timeout.</typeparam>
+ /// <typeparam name="TTimeout">The type of the elements in the timeout sequences used to indicate the timeout duration for each element in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to perform a timeout for.</param>
+ /// <param name="firstTimeout">Observable sequence that represents the timeout for the first element.</param>
+ /// <param name="timeoutDurationSelector">Selector to retrieve an observable sequence that represents the timeout between the current element and the next element.</param>
+ /// <param name="other">Sequence to return in case of a timeout.</param>
+ /// <returns>The source sequence switching to the other sequence in case of a timeout.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="firstTimeout"/> or <paramref name="timeoutDurationSelector"/> or <paramref name="other"/> is null.</exception>
+ public static IObservable<TSource> Timeout<TSource, TTimeout>(this IObservable<TSource> source, IObservable<TTimeout> firstTimeout, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector, IObservable<TSource> other)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (firstTimeout == null)
+ throw new ArgumentNullException("firstTimeout");
+ if (timeoutDurationSelector == null)
+ throw new ArgumentNullException("timeoutDurationSelector");
+ if (other == null)
+ throw new ArgumentNullException("other");
+
+ return s_impl.Timeout<TSource, TTimeout>(source, firstTimeout, timeoutDurationSelector, other);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region + Timer +
+
+ /// <summary>
+ /// Returns an observable sequence that produces a single value after the specified relative due time has elapsed.
+ /// </summary>
+ /// <param name="dueTime">Relative time at which to produce the value. If this value is less than or equal to TimeSpan.Zero, the timer will fire as soon as possible.</param>
+ /// <returns>An observable sequence that produces a value after the due time has elapsed.</returns>
+ public static IObservable<long> Timer(TimeSpan dueTime)
+ {
+ return s_impl.Timer(dueTime);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that produces a single value at the specified absolute due time.
+ /// </summary>
+ /// <param name="dueTime">Absolute time at which to produce the value. If this value is less than or equal to DateTimeOffset.UtcNow, the timer will fire as soon as possible.</param>
+ /// <returns>An observable sequence that produces a value at due time.</returns>
+ public static IObservable<long> Timer(DateTimeOffset dueTime)
+ {
+ return s_impl.Timer(dueTime);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that periodically produces a value after the specified initial relative due time has elapsed.
+ /// </summary>
+ /// <param name="dueTime">Relative time at which to produce the first value. If this value is less than or equal to TimeSpan.Zero, the timer will fire as soon as possible.</param>
+ /// <param name="period">Period to produce subsequent values. If this value is equal to TimeSpan.Zero, the timer will recur as fast as possible.</param>
+ /// <returns>An observable sequence that produces a value after due time has elapsed and then after each period.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+ public static IObservable<long> Timer(TimeSpan dueTime, TimeSpan period)
+ {
+ if (period < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("period");
+
+ return s_impl.Timer(dueTime, period);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that periodically produces a value starting at the specified initial absolute due time.
+ /// </summary>
+ /// <param name="dueTime">Absolute time at which to produce the first value. If this value is less than or equal to DateTimeOffset.UtcNow, the timer will fire as soon as possible.</param>
+ /// <param name="period">Period to produce subsequent values. If this value is equal to TimeSpan.Zero, the timer will recur as fast as possible.</param>
+ /// <returns>An observable sequence that produces a value at due time and then after each period.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+ public static IObservable<long> Timer(DateTimeOffset dueTime, TimeSpan period)
+ {
+ if (period < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("period");
+
+ return s_impl.Timer(dueTime, period);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that produces a single value after the specified relative due time has elapsed, using the specified scheduler to run the timer.
+ /// </summary>
+ /// <param name="dueTime">Relative time at which to produce the value. If this value is less than or equal to TimeSpan.Zero, the timer will fire as soon as possible.</param>
+ /// <param name="scheduler">Scheduler to run the timer on.</param>
+ /// <returns>An observable sequence that produces a value after the due time has elapsed.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ public static IObservable<long> Timer(TimeSpan dueTime, IScheduler scheduler)
+ {
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Timer(dueTime, scheduler);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that produces a single value at the specified absolute due time, using the specified scheduler to run the timer.
+ /// </summary>
+ /// <param name="dueTime">Absolute time at which to produce the value. If this value is less than or equal to DateTimeOffset.UtcNow, the timer will fire as soon as possible.</param>
+ /// <param name="scheduler">Scheduler to run the timer on.</param>
+ /// <returns>An observable sequence that produces a value at due time.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ public static IObservable<long> Timer(DateTimeOffset dueTime, IScheduler scheduler)
+ {
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Timer(dueTime, scheduler);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that periodically produces a value after the specified initial relative due time has elapsed, using the specified scheduler to run timers.
+ /// </summary>
+ /// <param name="dueTime">Relative time at which to produce the first value. If this value is less than or equal to TimeSpan.Zero, the timer will fire as soon as possible.</param>
+ /// <param name="period">Period to produce subsequent values. If this value is equal to TimeSpan.Zero, the timer will recur as fast as possible.</param>
+ /// <param name="scheduler">Scheduler to run timers on.</param>
+ /// <returns>An observable sequence that produces a value after due time has elapsed and then each period.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ public static IObservable<long> Timer(TimeSpan dueTime, TimeSpan period, IScheduler scheduler)
+ {
+ if (period < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("period");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Timer(dueTime, period, scheduler);
+ }
+
+ /// <summary>
+ /// Returns an observable sequence that periodically produces a value starting at the specified initial absolute due time, using the specified scheduler to run timers.
+ /// </summary>
+ /// <param name="dueTime">Absolute time at which to produce the first value. If this value is less than or equal to DateTimeOffset.UtcNow, the timer will fire as soon as possible.</param>
+ /// <param name="period">Period to produce subsequent values. If this value is equal to TimeSpan.Zero, the timer will recur as fast as possible.</param>
+ /// <param name="scheduler">Scheduler to run timers on.</param>
+ /// <returns>An observable sequence that produces a value at due time and then after each period.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+ public static IObservable<long> Timer(DateTimeOffset dueTime, TimeSpan period, IScheduler scheduler)
+ {
+ if (period < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("period");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Timer(dueTime, period, scheduler);
+ }
+
+ #endregion
+
+ #region + Timestamp +
+
+ /// <summary>
+ /// Timestamps each element in an observable sequence using the local system clock.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to timestamp elements for.</param>
+ /// <returns>An observable sequence with timestamp information on elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ public static IObservable<Timestamped<TSource>> Timestamp<TSource>(this IObservable<TSource> source)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+
+ return s_impl.Timestamp<TSource>(source);
+ }
+
+ /// <summary>
+ /// Timestamp each element in an observable sequence using the clock of the specified scheduler.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
+ /// <param name="source">Source sequence to timestamp elements for.</param>
+ /// <param name="scheduler">Scheduler used to compute timestamps.</param>
+ /// <returns>An observable sequence with timestamp information on elements.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ public static IObservable<Timestamped<TSource>> Timestamp<TSource>(this IObservable<TSource> source, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Timestamp<TSource>(source, scheduler);
+ }
+
+ #endregion
+
+ #region + Window +
+
+ #region TimeSpan only
+
+ /// <summary>
+ /// Projects each element of an observable sequence into consecutive non-overlapping windows which are produced based on timing information.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="timeSpan">Length of each window.</param>
+ /// <returns>The sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create windows as fast as it can.
+ /// Because all source sequence elements end up in one of the windows, some windows won't have a zero time span. This is a side-effect of the asynchrony introduced
+ /// by the scheduler, where the action to close the current window and to create a new window may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<IObservable<TSource>> Window<TSource>(this IObservable<TSource> source, TimeSpan timeSpan)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+
+ return s_impl.Window<TSource>(source, timeSpan);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into consecutive non-overlapping windows which are produced based on timing information, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="timeSpan">Length of each window.</param>
+ /// <param name="scheduler">Scheduler to run windowing timers on.</param>
+ /// <returns>An observable sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create windows as fast as it can.
+ /// Because all source sequence elements end up in one of the windows, some windows won't have a zero time span. This is a side-effect of the asynchrony introduced
+ /// by the scheduler, where the action to close the current window and to create a new window may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<IObservable<TSource>> Window<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Window<TSource>(source, timeSpan, scheduler);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into zero or more windows which are produced based on timing information.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="timeSpan">Length of each window.</param>
+ /// <param name="timeShift">Interval between creation of consecutive windows.</param>
+ /// <returns>An observable sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> or <paramref name="timeSpan"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create windows with minimum duration
+ /// length. However, some windows won't have a zero time span. This is a side-effect of the asynchrony introduced by the scheduler, where the action to close the
+ /// current window may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </para>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeShift"/> is not recommended but supported, causing the scheduler to create windows as fast as it can.
+ /// However, this doesn't mean all windows will start at the beginning of the source sequence. This is a side-effect of the asynchrony introduced by the scheduler,
+ /// where the action to create a new window may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </para>
+ /// </remarks>
+ public static IObservable<IObservable<TSource>> Window<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+ if (timeShift < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeShift");
+
+ return s_impl.Window<TSource>(source, timeSpan, timeShift);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into zero or more windows which are produced based on timing information, using the specified scheduler to run timers.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="timeSpan">Length of each window.</param>
+ /// <param name="timeShift">Interval between creation of consecutive windows.</param>
+ /// <param name="scheduler">Scheduler to run windowing timers on.</param>
+ /// <returns>An observable sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> or <paramref name="timeSpan"/> is less than TimeSpan.Zero.</exception>
+ /// <remarks>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create windows with minimum duration
+ /// length. However, some windows won't have a zero time span. This is a side-effect of the asynchrony introduced by the scheduler, where the action to close the
+ /// current window may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </para>
+ /// <para>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeShift"/> is not recommended but supported, causing the scheduler to create windows as fast as it can.
+ /// However, this doesn't mean all windows will start at the beginning of the source sequence. This is a side-effect of the asynchrony introduced by the scheduler,
+ /// where the action to create a new window may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </para>
+ /// </remarks>
+ public static IObservable<IObservable<TSource>> Window<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+ if (timeShift < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeShift");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Window<TSource>(source, timeSpan, timeShift, scheduler);
+ }
+
+ #endregion
+
+ #region TimeSpan + int
+
+ /// <summary>
+ /// Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed.
+ /// A useful real-world analogy of this overload is the behavior of a ferry leaving the dock when all seats are taken, or at the scheduled time of departure, whichever event occurs first.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="timeSpan">Maximum time length of a window.</param>
+ /// <param name="count">Maximum element count of a window.</param>
+ /// <returns>An observable sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> is less than TimeSpan.Zero. -or- <paramref name="count"/> is less than or equal to zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create windows as fast as it can.
+ /// Because all source sequence elements end up in one of the windows, some windows won't have a zero time span. This is a side-effect of the asynchrony introduced
+ /// by the scheduler, where the action to close the current window and to create a new window may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<IObservable<TSource>> Window<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, int count)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+ if (count <= 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ return s_impl.Window<TSource>(source, timeSpan, count);
+ }
+
+ /// <summary>
+ /// Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed, using the specified scheduler to run timers.
+ /// A useful real-world analogy of this overload is the behavior of a ferry leaving the dock when all seats are taken, or at the scheduled time of departure, whichever event occurs first.
+ /// </summary>
+ /// <typeparam name="TSource">The type of the elements in the source sequence, and in the windows in the result sequence.</typeparam>
+ /// <param name="source">Source sequence to produce windows over.</param>
+ /// <param name="timeSpan">Maximum time length of a window.</param>
+ /// <param name="count">Maximum element count of a window.</param>
+ /// <param name="scheduler">Scheduler to run windowing timers on.</param>
+ /// <returns>An observable sequence of windows.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> is less than TimeSpan.Zero. -or- <paramref name="count"/> is less than or equal to zero.</exception>
+ /// <remarks>
+ /// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create windows as fast as it can.
+ /// Because all source sequence elements end up in one of the windows, some windows won't have a zero time span. This is a side-effect of the asynchrony introduced
+ /// by the scheduler, where the action to close the current window and to create a new window may not execute immediately, despite the TimeSpan.Zero due time.
+ /// </remarks>
+ public static IObservable<IObservable<TSource>> Window<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, int count, IScheduler scheduler)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (timeSpan < TimeSpan.Zero)
+ throw new ArgumentOutOfRangeException("timeSpan");
+ if (count <= 0)
+ throw new ArgumentOutOfRangeException("count");
+ if (scheduler == null)
+ throw new ArgumentNullException("scheduler");
+
+ return s_impl.Window<TSource>(source, timeSpan, count, scheduler);
+ }
+
+ #endregion
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable_.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable_.cs
new file mode 100644
index 0000000..a7c6b0e
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable_.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+namespace System.Reactive.Linq
+{
+ /// <summary>
+ /// Provides a set of static methods for writing in-memory queries over observable sequences.
+ /// </summary>
+ public static partial class Observable
+ {
+ private static IQueryLanguage s_impl = QueryServices.GetQueryImpl<IQueryLanguage>(new QueryLanguage());
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/AddRef.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/AddRef.cs
new file mode 100644
index 0000000..3fc6962
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/AddRef.cs
@@ -0,0 +1,55 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class AddRef<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly RefCountDisposable _refCount;
+
+ public AddRef(IObservable<TSource> source, RefCountDisposable refCount)
+ {
+ _source = source;
+ _refCount = refCount;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var d = new CompositeDisposable(_refCount.GetDisposable(), cancel);
+
+ var sink = new _(observer, d);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ public _(IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Aggregate.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Aggregate.cs
new file mode 100644
index 0000000..d1b6ef8
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Aggregate.cs
@@ -0,0 +1,158 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Aggregate<TSource, TAccumulate, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly TAccumulate _seed;
+ private readonly Func<TAccumulate, TSource, TAccumulate> _accumulator;
+ private readonly Func<TAccumulate, TResult> _resultSelector;
+
+ public Aggregate(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector)
+ {
+ _source = source;
+ _seed = seed;
+ _accumulator = accumulator;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TResult>, IObserver<TSource>
+ {
+ private readonly Aggregate<TSource, TAccumulate, TResult> _parent;
+ private TAccumulate _accumulation;
+
+ public _(Aggregate<TSource, TAccumulate, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _accumulation = _parent._seed;
+ }
+
+ public void OnNext(TSource value)
+ {
+ try
+ {
+ _accumulation = _parent._accumulator(_accumulation, value);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ var result = default(TResult);
+ try
+ {
+ result = _parent._resultSelector(_accumulation);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(result);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class Aggregate<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TSource, TSource> _accumulator;
+
+ public Aggregate(IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
+ {
+ _source = source;
+ _accumulator = accumulator;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Aggregate<TSource> _parent;
+ private TSource _accumulation;
+ private bool _hasAccumulation;
+
+ public _(Aggregate<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _accumulation = default(TSource);
+ _hasAccumulation = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (!_hasAccumulation)
+ {
+ _accumulation = value;
+ _hasAccumulation = true;
+ }
+ else
+ {
+ try
+ {
+ _accumulation = _parent._accumulator(_accumulation, value);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasAccumulation)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ base.Dispose();
+ }
+ else
+ {
+ base._observer.OnNext(_accumulation);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/All.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/All.cs
new file mode 100644
index 0000000..09c825d
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/All.cs
@@ -0,0 +1,73 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class All<TSource> : Producer<bool>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+
+ public All(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ _source = source;
+ _predicate = predicate;
+ }
+
+ protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<bool>, IObserver<TSource>
+ {
+ private readonly All<TSource> _parent;
+
+ public _(All<TSource> parent, IObserver<bool> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var res = false;
+ try
+ {
+ res = _parent._predicate(value);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (!res)
+ {
+ base._observer.OnNext(false);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(true);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Amb.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Amb.cs
new file mode 100644
index 0000000..7272cee
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Amb.cs
@@ -0,0 +1,173 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Amb<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _left;
+ private readonly IObservable<TSource> _right;
+
+ public Amb(IObservable<TSource> left, IObservable<TSource> right)
+ {
+ _left = left;
+ _right = right;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>
+ {
+ private readonly Amb<TSource> _parent;
+
+ public _(Amb<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private AmbState _choice;
+
+ public IDisposable Run()
+ {
+ var ls = new SingleAssignmentDisposable();
+ var rs = new SingleAssignmentDisposable();
+ var d = new CompositeDisposable(ls, rs);
+
+ var gate = new object();
+
+ var lo = new AmbObserver();
+ lo._disposable = d;
+ lo._target = new DecisionObserver(this, gate, AmbState.Left, ls, rs, lo);
+
+ var ro = new AmbObserver();
+ ro._disposable = d;
+ ro._target = new DecisionObserver(this, gate, AmbState.Right, rs, ls, ro);
+
+ _choice = AmbState.Neither;
+
+ ls.Disposable = _parent._left.SubscribeSafe(lo);
+ rs.Disposable = _parent._right.SubscribeSafe(ro);
+
+ return d;
+ }
+
+ class DecisionObserver : IObserver<TSource>
+ {
+ private readonly _ _parent;
+ private readonly AmbState _me;
+ private readonly IDisposable _subscription;
+ private readonly IDisposable _otherSubscription;
+ private readonly object _gate;
+ private readonly AmbObserver _observer;
+
+ public DecisionObserver(_ parent, object gate, AmbState me, IDisposable subscription, IDisposable otherSubscription, AmbObserver observer)
+ {
+ _parent = parent;
+ _gate = gate;
+ _me = me;
+ _subscription = subscription;
+ _otherSubscription = otherSubscription;
+ _observer = observer;
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ if (_parent._choice == AmbState.Neither)
+ {
+ _parent._choice = _me;
+ _otherSubscription.Dispose();
+ _observer._disposable = _subscription;
+ _observer._target = _parent._observer;
+ }
+
+ if (_parent._choice == _me)
+ _parent._observer.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ if (_parent._choice == AmbState.Neither)
+ {
+ _parent._choice = _me;
+ _otherSubscription.Dispose();
+ _observer._disposable = _subscription;
+ _observer._target = _parent._observer;
+ }
+
+ if (_parent._choice == _me)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ if (_parent._choice == AmbState.Neither)
+ {
+ _parent._choice = _me;
+ _otherSubscription.Dispose();
+ _observer._disposable = _subscription;
+ _observer._target = _parent._observer;
+ }
+
+ if (_parent._choice == _me)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+ }
+
+ class AmbObserver : IObserver<TSource>
+ {
+ public IObserver<TSource> _target;
+
+ public IDisposable _disposable;
+
+ public void OnNext(TSource value)
+ {
+ _target.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ _target.OnError(error);
+ _disposable.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ _target.OnCompleted();
+ _disposable.Dispose();
+ }
+ }
+
+ enum AmbState
+ {
+ Left,
+ Right,
+ Neither
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Any.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Any.cs
new file mode 100644
index 0000000..1414bdd
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Any.cs
@@ -0,0 +1,115 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Any<TSource> : Producer<bool>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+
+ public Any(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ public Any(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ _source = source;
+ _predicate = predicate;
+ }
+
+ protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_predicate != null)
+ {
+ var sink = new π(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<bool>, IObserver<TSource>
+ {
+ public _(IObserver<bool> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(true);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(false);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class π : Sink<bool>, IObserver<TSource>
+ {
+ private readonly Any<TSource> _parent;
+
+ public π(Any<TSource> parent, IObserver<bool> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var res = false;
+ try
+ {
+ res = _parent._predicate(value);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (res)
+ {
+ base._observer.OnNext(true);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(false);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/AsObservable.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/AsObservable.cs
new file mode 100644
index 0000000..09d5f14
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/AsObservable.cs
@@ -0,0 +1,60 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class AsObservable<TSource> : Producer<TSource>, IEvaluatableObservable<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+
+ public AsObservable(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ public IObservable<TSource> Ω()
+ {
+ return this;
+ }
+
+ public IObservable<TSource> Eval()
+ {
+ return _source;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ public _(IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Average.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Average.cs
new file mode 100644
index 0000000..fb2d6b7
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Average.cs
@@ -0,0 +1,703 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class AverageDouble : Producer<double>
+ {
+ private readonly IObservable<double> _source;
+
+ public AverageDouble(IObservable<double> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double>, IObserver<double>
+ {
+ private double _sum;
+ private long _count;
+
+ public _(IObserver<double> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0.0;
+ _count = 0L;
+ }
+
+ public void OnNext(double value)
+ {
+ try
+ {
+ checked
+ {
+ _sum += value;
+ _count++;
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_count > 0)
+ {
+ base._observer.OnNext(_sum / _count);
+ base._observer.OnCompleted();
+ }
+ else
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class AverageSingle : Producer<float>
+ {
+ private readonly IObservable<float> _source;
+
+ public AverageSingle(IObservable<float> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<float> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<float>, IObserver<float>
+ {
+ private double _sum; // NOTE: Uses a different accumulator type (double), conform LINQ to Objects.
+ private long _count;
+
+ public _(IObserver<float> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0.0;
+ _count = 0L;
+ }
+
+ public void OnNext(float value)
+ {
+ try
+ {
+ checked
+ {
+ _sum += value;
+ _count++;
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_count > 0)
+ {
+ base._observer.OnNext((float)(_sum / _count));
+ base._observer.OnCompleted();
+ }
+ else
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class AverageDecimal : Producer<decimal>
+ {
+ private readonly IObservable<decimal> _source;
+
+ public AverageDecimal(IObservable<decimal> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<decimal> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<decimal>, IObserver<decimal>
+ {
+ private decimal _sum;
+ private long _count;
+
+ public _(IObserver<decimal> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0M;
+ _count = 0L;
+ }
+
+ public void OnNext(decimal value)
+ {
+ try
+ {
+ checked
+ {
+ _sum += value;
+ _count++;
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_count > 0)
+ {
+ base._observer.OnNext(_sum / _count);
+ base._observer.OnCompleted();
+ }
+ else
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class AverageInt32 : Producer<double>
+ {
+ private readonly IObservable<int> _source;
+
+ public AverageInt32(IObservable<int> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double>, IObserver<int>
+ {
+ private long _sum;
+ private long _count;
+
+ public _(IObserver<double> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0L;
+ _count = 0L;
+ }
+
+ public void OnNext(int value)
+ {
+ try
+ {
+ checked
+ {
+ _sum += value;
+ _count++;
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_count > 0)
+ {
+ base._observer.OnNext((double)_sum / _count);
+ base._observer.OnCompleted();
+ }
+ else
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class AverageInt64 : Producer<double>
+ {
+ private readonly IObservable<long> _source;
+
+ public AverageInt64(IObservable<long> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double>, IObserver<long>
+ {
+ private long _sum;
+ private long _count;
+
+ public _(IObserver<double> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0L;
+ _count = 0L;
+ }
+
+ public void OnNext(long value)
+ {
+ try
+ {
+ checked
+ {
+ _sum += value;
+ _count++;
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_count > 0)
+ {
+ base._observer.OnNext((double)_sum / _count);
+ base._observer.OnCompleted();
+ }
+ else
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class AverageDoubleNullable : Producer<double?>
+ {
+ private readonly IObservable<double?> _source;
+
+ public AverageDoubleNullable(IObservable<double?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double?>, IObserver<double?>
+ {
+ private double _sum;
+ private long _count;
+
+ public _(IObserver<double?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0.0;
+ _count = 0L;
+ }
+
+ public void OnNext(double? value)
+ {
+ try
+ {
+ checked
+ {
+ if (value != null)
+ {
+ _sum += value.Value;
+ _count++;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_count > 0)
+ {
+ base._observer.OnNext(_sum / _count);
+ }
+ else
+ {
+ base._observer.OnNext(null);
+ }
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class AverageSingleNullable : Producer<float?>
+ {
+ private readonly IObservable<float?> _source;
+
+ public AverageSingleNullable(IObservable<float?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<float?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<float?>, IObserver<float?>
+ {
+ private double _sum; // NOTE: Uses a different accumulator type (double), conform LINQ to Objects.
+ private long _count;
+
+ public _(IObserver<float?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0.0;
+ _count = 0L;
+ }
+
+ public void OnNext(float? value)
+ {
+ try
+ {
+ checked
+ {
+ if (value != null)
+ {
+ _sum += value.Value;
+ _count++;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_count > 0)
+ {
+ base._observer.OnNext((float)(_sum / _count));
+ }
+ else
+ {
+ base._observer.OnNext(null);
+ }
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class AverageDecimalNullable : Producer<decimal?>
+ {
+ private readonly IObservable<decimal?> _source;
+
+ public AverageDecimalNullable(IObservable<decimal?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<decimal?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<decimal?>, IObserver<decimal?>
+ {
+ private decimal _sum;
+ private long _count;
+
+ public _(IObserver<decimal?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0M;
+ _count = 0L;
+ }
+
+ public void OnNext(decimal? value)
+ {
+ try
+ {
+ checked
+ {
+ if (value != null)
+ {
+ _sum += value.Value;
+ _count++;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_count > 0)
+ {
+ base._observer.OnNext(_sum / _count);
+ }
+ else
+ {
+ base._observer.OnNext(null);
+ }
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class AverageInt32Nullable : Producer<double?>
+ {
+ private readonly IObservable<int?> _source;
+
+ public AverageInt32Nullable(IObservable<int?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double?>, IObserver<int?>
+ {
+ private long _sum;
+ private long _count;
+
+ public _(IObserver<double?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0L;
+ _count = 0L;
+ }
+
+ public void OnNext(int? value)
+ {
+ try
+ {
+ checked
+ {
+ if (value != null)
+ {
+ _sum += value.Value;
+ _count++;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_count > 0)
+ {
+ base._observer.OnNext((double)_sum / _count);
+ }
+ else
+ {
+ base._observer.OnNext(null);
+ }
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class AverageInt64Nullable : Producer<double?>
+ {
+ private readonly IObservable<long?> _source;
+
+ public AverageInt64Nullable(IObservable<long?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double?>, IObserver<long?>
+ {
+ private long _sum;
+ private long _count;
+
+ public _(IObserver<double?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0L;
+ _count = 0L;
+ }
+
+ public void OnNext(long? value)
+ {
+ try
+ {
+ checked
+ {
+ if (value != null)
+ {
+ _sum += value.Value;
+ _count++;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_count > 0)
+ {
+ base._observer.OnNext((double)_sum / _count);
+ }
+ else
+ {
+ base._observer.OnNext(null);
+ }
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Buffer.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Buffer.cs
new file mode 100644
index 0000000..a82b550
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Buffer.cs
@@ -0,0 +1,709 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Buffer<TSource> : Producer<IList<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly int _count;
+ private readonly int _skip;
+
+ private readonly TimeSpan _timeSpan;
+ private readonly TimeSpan _timeShift;
+ private readonly IScheduler _scheduler;
+
+ public Buffer(IObservable<TSource> source, int count, int skip)
+ {
+ _source = source;
+ _count = count;
+ _skip = skip;
+ }
+
+ public Buffer(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler)
+ {
+ _source = source;
+ _timeSpan = timeSpan;
+ _timeShift = timeShift;
+ _scheduler = scheduler;
+ }
+
+ public Buffer(IObservable<TSource> source, TimeSpan timeSpan, int count, IScheduler scheduler)
+ {
+ _source = source;
+ _timeSpan = timeSpan;
+ _count = count;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_scheduler == null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else if (_count > 0)
+ {
+ var sink = new μ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ if (_timeSpan == _timeShift)
+ {
+ var sink = new π(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+ }
+
+ class _ : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private readonly Buffer<TSource> _parent;
+
+ public _(Buffer<TSource> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private Queue<IList<TSource>> _queue;
+ private int _n;
+
+ public IDisposable Run()
+ {
+ _queue = new Queue<IList<TSource>>();
+ _n = 0;
+
+ CreateWindow();
+ return _parent._source.SubscribeSafe(this);
+ }
+
+ private void CreateWindow()
+ {
+ var s = new List<TSource>();
+ _queue.Enqueue(s);
+ }
+
+ public void OnNext(TSource value)
+ {
+ foreach (var s in _queue)
+ s.Add(value);
+
+ var c = _n - _parent._count + 1;
+ if (c >= 0 && c % _parent._skip == 0)
+ {
+ var s = _queue.Dequeue();
+ if (s.Count > 0)
+ base._observer.OnNext(s);
+ }
+
+ _n++;
+ if (_n % _parent._skip == 0)
+ CreateWindow();
+ }
+
+ public void OnError(Exception error)
+ {
+ while (_queue.Count > 0)
+ _queue.Dequeue().Clear();
+
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ while (_queue.Count > 0)
+ {
+ var s = _queue.Dequeue();
+ if (s.Count > 0)
+ base._observer.OnNext(s);
+ }
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private readonly Buffer<TSource> _parent;
+
+ public τ(Buffer<TSource> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private TimeSpan _totalTime;
+ private TimeSpan _nextShift;
+ private TimeSpan _nextSpan;
+
+ private object _gate;
+ private Queue<List<TSource>> _q;
+
+ private SerialDisposable _timerD;
+
+ public IDisposable Run()
+ {
+ _totalTime = TimeSpan.Zero;
+ _nextShift = _parent._timeShift;
+ _nextSpan = _parent._timeSpan;
+
+ _gate = new object();
+ _q = new Queue<List<TSource>>();
+
+ _timerD = new SerialDisposable();
+
+ CreateWindow();
+ CreateTimer();
+
+ var subscription = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable { _timerD, subscription };
+ }
+
+ private void CreateWindow()
+ {
+ var s = new List<TSource>();
+ _q.Enqueue(s);
+ }
+
+ private void CreateTimer()
+ {
+ var m = new SingleAssignmentDisposable();
+ _timerD.Disposable = m;
+
+ var isSpan = false;
+ var isShift = false;
+ if (_nextSpan == _nextShift)
+ {
+ isSpan = true;
+ isShift = true;
+ }
+ else if (_nextSpan < _nextShift)
+ isSpan = true;
+ else
+ isShift = true;
+
+ var newTotalTime = isSpan ? _nextSpan : _nextShift;
+ var ts = newTotalTime - _totalTime;
+ _totalTime = newTotalTime;
+
+ if (isSpan)
+ _nextSpan += _parent._timeShift;
+ if (isShift)
+ _nextShift += _parent._timeShift;
+
+ m.Disposable = _parent._scheduler.Schedule(new State { isSpan = isSpan, isShift = isShift }, ts, Tick);
+ }
+
+ struct State
+ {
+ public bool isSpan;
+ public bool isShift;
+ }
+
+ private IDisposable Tick(IScheduler self, State state)
+ {
+ lock (_gate)
+ {
+ //
+ // Before v2, the two operations below were reversed. This doesn't have an observable
+ // difference for Buffer, but is done to keep code consistent with Window, where we
+ // took a breaking change in v2 to ensure consistency across overloads. For more info,
+ // see the comment in Tick for Window.
+ //
+ if (state.isSpan)
+ {
+ var s = _q.Dequeue();
+ base._observer.OnNext(s);
+ }
+
+ if (state.isShift)
+ {
+ CreateWindow();
+ }
+ }
+
+ CreateTimer();
+
+ return Disposable.Empty;
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ foreach (var s in _q)
+ s.Add(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ while (_q.Count > 0)
+ _q.Dequeue().Clear();
+
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ while (_q.Count > 0)
+ base._observer.OnNext(_q.Dequeue());
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class π : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private readonly Buffer<TSource> _parent;
+
+ public π(Buffer<TSource> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private List<TSource> _list;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _list = new List<TSource>();
+
+ var d = _parent._scheduler.SchedulePeriodic(_parent._timeSpan, Tick);
+ var s = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(d, s);
+ }
+
+ private void Tick()
+ {
+ lock (_gate)
+ {
+ base._observer.OnNext(_list);
+ _list = new List<TSource>();
+ }
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ _list.Add(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ _list.Clear();
+
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ base._observer.OnNext(_list);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class μ : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private readonly Buffer<TSource> _parent;
+
+ public μ(Buffer<TSource> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private IList<TSource> _s;
+ private int _n;
+ private int _windowId;
+
+ private SerialDisposable _timerD;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _s = default(IList<TSource>);
+ _n = 0;
+ _windowId = 0;
+
+ _timerD = new SerialDisposable();
+
+ _s = new List<TSource>();
+ CreateTimer(0);
+
+ var subscription = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable { _timerD, subscription };
+ }
+
+ private void CreateTimer(int id)
+ {
+ var m = new SingleAssignmentDisposable();
+ _timerD.Disposable = m;
+
+ m.Disposable = _parent._scheduler.Schedule(id, _parent._timeSpan, Tick);
+ }
+
+ private IDisposable Tick(IScheduler self, int id)
+ {
+ var d = Disposable.Empty;
+
+ var newId = 0;
+ lock (_gate)
+ {
+ if (id != _windowId)
+ return d;
+
+ _n = 0;
+ newId = ++_windowId;
+
+ var res = _s;
+ _s = new List<TSource>();
+ base._observer.OnNext(res);
+ }
+
+ CreateTimer(newId);
+
+ return d;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var newWindow = false;
+ var newId = 0;
+
+ lock (_gate)
+ {
+ _s.Add(value);
+
+ _n++;
+ if (_n == _parent._count)
+ {
+ newWindow = true;
+ _n = 0;
+ newId = ++_windowId;
+
+ var res = _s;
+ _s = new List<TSource>();
+ base._observer.OnNext(res);
+ }
+ }
+
+ if (newWindow)
+ CreateTimer(newId);
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ _s.Clear();
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ base._observer.OnNext(_s);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+
+ class Buffer<TSource, TBufferClosing> : Producer<IList<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<IObservable<TBufferClosing>> _bufferClosingSelector;
+ private readonly IObservable<TBufferClosing> _bufferBoundaries;
+
+ public Buffer(IObservable<TSource> source, Func<IObservable<TBufferClosing>> bufferClosingSelector)
+ {
+ _source = source;
+ _bufferClosingSelector = bufferClosingSelector;
+ }
+
+ public Buffer(IObservable<TSource> source, IObservable<TBufferClosing> bufferBoundaries)
+ {
+ _source = source;
+ _bufferBoundaries = bufferBoundaries;
+ }
+
+ protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_bufferClosingSelector != null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new β(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private readonly Buffer<TSource, TBufferClosing> _parent;
+
+ public _(Buffer<TSource, TBufferClosing> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private IList<TSource> _buffer;
+ private object _gate;
+ private AsyncLock _bufferGate;
+
+ private SerialDisposable _m;
+
+ public IDisposable Run()
+ {
+ _buffer = new List<TSource>();
+ _gate = new object();
+ _bufferGate = new AsyncLock();
+
+ _m = new SerialDisposable();
+ var groupDisposable = new CompositeDisposable(2) { _m };
+
+ groupDisposable.Add(_parent._source.SubscribeSafe(this));
+
+ _bufferGate.Wait(CreateBufferClose);
+
+ return groupDisposable;
+ }
+
+ private void CreateBufferClose()
+ {
+ var bufferClose = default(IObservable<TBufferClosing>);
+ try
+ {
+ bufferClose = _parent._bufferClosingSelector();
+ }
+ catch (Exception exception)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ }
+ return;
+ }
+
+ var closingSubscription = new SingleAssignmentDisposable();
+ _m.Disposable = closingSubscription;
+ closingSubscription.Disposable = bufferClose.SubscribeSafe(new ω(this, closingSubscription));
+ }
+
+ private void CloseBuffer(IDisposable closingSubscription)
+ {
+ closingSubscription.Dispose();
+
+ lock (_gate)
+ {
+ var res = _buffer;
+ _buffer = new List<TSource>();
+ base._observer.OnNext(res);
+ }
+
+ _bufferGate.Wait(CreateBufferClose);
+ }
+
+ class ω : IObserver<TBufferClosing>
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+
+ public ω(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ public void OnNext(TBufferClosing value)
+ {
+ _parent.CloseBuffer(_self);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.OnError(error);
+ }
+
+ public void OnCompleted()
+ {
+ _parent.CloseBuffer(_self);
+ }
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ _buffer.Add(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ _buffer.Clear();
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ base._observer.OnNext(_buffer);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class β : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private readonly Buffer<TSource, TBufferClosing> _parent;
+
+ public β(Buffer<TSource, TBufferClosing> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private IList<TSource> _buffer;
+ private object _gate;
+
+ private RefCountDisposable _refCountDisposable;
+
+ public IDisposable Run()
+ {
+ _buffer = new List<TSource>();
+ _gate = new object();
+
+ var d = new CompositeDisposable(2);
+ _refCountDisposable = new RefCountDisposable(d);
+
+ d.Add(_parent._source.SubscribeSafe(this));
+ d.Add(_parent._bufferBoundaries.SubscribeSafe(new ω(this)));
+
+ return _refCountDisposable;
+ }
+
+ class ω : IObserver<TBufferClosing>
+ {
+ private readonly β _parent;
+
+ public ω(β parent)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TBufferClosing value)
+ {
+ lock (_parent._gate)
+ {
+ var res = _parent._buffer;
+ _parent._buffer = new List<TSource>();
+ _parent._observer.OnNext(res);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.OnError(error);
+ }
+
+ public void OnCompleted()
+ {
+ _parent.OnCompleted();
+ }
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ _buffer.Add(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ _buffer.Clear();
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ base._observer.OnNext(_buffer);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Case.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Case.cs
new file mode 100644
index 0000000..b104050
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Case.cs
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Case<TValue, TResult> : Producer<TResult>, IEvaluatableObservable<TResult>
+ {
+ private readonly Func<TValue> _selector;
+ private readonly IDictionary<TValue, IObservable<TResult>> _sources;
+ private readonly IObservable<TResult> _defaultSource;
+
+ public Case(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources, IObservable<TResult> defaultSource)
+ {
+ _selector = selector;
+ _sources = sources;
+ _defaultSource = defaultSource;
+ }
+
+ public IObservable<TResult> Eval()
+ {
+ var res = default(IObservable<TResult>);
+ if (_sources.TryGetValue(_selector(), out res))
+ return res;
+
+ return _defaultSource;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>, IObserver<TResult>
+ {
+ private readonly Case<TValue, TResult> _parent;
+
+ public _(Case<TValue, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var result = default(IObservable<TResult>);
+ try
+ {
+ result = _parent.Eval();
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ return result.SubscribeSafe(this);
+ }
+
+ public void OnNext(TResult value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Cast.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Cast.cs
new file mode 100644
index 0000000..48820b3
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Cast.cs
@@ -0,0 +1,62 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Cast<TSource, TResult> : Producer<TResult> /* Could optimize further by deriving from Select<TResult> and providing Ω<TResult2>. We're not doing this (yet) for debuggability. */
+ {
+ private readonly IObservable<TSource> _source;
+
+ public Cast(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TResult>, IObserver<TSource>
+ {
+ public _(IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public void OnNext(TSource value)
+ {
+ var result = default(TResult);
+ try
+ {
+ result = (TResult)(object)value;
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(result);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Catch.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Catch.cs
new file mode 100644
index 0000000..71e0037
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Catch.cs
@@ -0,0 +1,183 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Catch<TSource> : Producer<TSource>
+ {
+ private readonly IEnumerable<IObservable<TSource>> _sources;
+
+ public Catch(IEnumerable<IObservable<TSource>> sources)
+ {
+ _sources = sources;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return sink.Run(_sources);
+ }
+
+ class _ : TailRecursiveSink<TSource>
+ {
+ public _(IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ protected override IEnumerable<IObservable<TSource>> Extract(IObservable<TSource> source)
+ {
+ var @catch = source as Catch<TSource>;
+ if (@catch != null)
+ return @catch._sources;
+
+ return null;
+ }
+
+ public override void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ private Exception _lastException;
+
+ public override void OnError(Exception error)
+ {
+ _lastException = error;
+ _recurse();
+ }
+
+ public override void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+
+ protected override void Done()
+ {
+ if (_lastException != null)
+ base._observer.OnError(_lastException);
+ else
+ base._observer.OnCompleted();
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class Catch<TSource, TException> : Producer<TSource> where TException : Exception
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TException, IObservable<TSource>> _handler;
+
+ public Catch(IObservable<TSource> source, Func<TException, IObservable<TSource>> handler)
+ {
+ _source = source;
+ _handler = handler;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Catch<TSource, TException> _parent;
+
+ public _(Catch<TSource, TException> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private SerialDisposable _subscription;
+
+ public IDisposable Run()
+ {
+ _subscription = new SerialDisposable();
+
+ var d1 = new SingleAssignmentDisposable();
+ _subscription.Disposable = d1;
+ d1.Disposable = _parent._source.SubscribeSafe(this);
+
+ return _subscription;
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ var e = error as TException;
+ if (e != null)
+ {
+ var result = default(IObservable<TSource>);
+ try
+ {
+ result = _parent._handler(e);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ _subscription.Disposable = d;
+ d.Disposable = result.SubscribeSafe(new ε(this));
+ }
+ else
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+
+ class ε : IObserver<TSource>
+ {
+ private readonly _ _parent;
+
+ public ε(_ parent)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ _parent._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Collect.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Collect.cs
new file mode 100644
index 0000000..2cfd240
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Collect.cs
@@ -0,0 +1,139 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive;
+using System.Reactive.Threading;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Collect<TSource, TResult> : PushToPullAdapter<TSource, TResult>
+ {
+ private readonly Func<TResult> _getInitialCollector;
+ private readonly Func<TResult, TSource, TResult> _merge;
+ private readonly Func<TResult, TResult> _getNewCollector;
+
+ public Collect(IObservable<TSource> source, Func<TResult> getInitialCollector, Func<TResult, TSource, TResult> merge, Func<TResult, TResult> getNewCollector)
+ : base(source)
+ {
+ _getInitialCollector = getInitialCollector;
+ _merge = merge;
+ _getNewCollector = getNewCollector;
+ }
+
+ protected override PushToPullSink<TSource, TResult> Run(IDisposable subscription)
+ {
+ var sink = new _(this, subscription);
+ sink.Initialize();
+ return sink;
+ }
+
+ class _ : PushToPullSink<TSource, TResult>
+ {
+ private readonly Collect<TSource, TResult> _parent;
+
+ public _(Collect<TSource, TResult> parent, IDisposable subscription)
+ : base(subscription)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private TResult _collector;
+ private bool _hasFailed;
+ private Exception _error;
+ private bool _hasCompleted;
+ private bool _done;
+
+ public void Initialize()
+ {
+ _gate = new object();
+ _collector = _parent._getInitialCollector();
+ }
+
+ public override void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ try
+ {
+ _collector = _parent._merge(_collector, value);
+ }
+ catch (Exception ex)
+ {
+ _error = ex;
+ _hasFailed = true;
+
+ base.Dispose();
+ }
+ }
+ }
+
+ public override void OnError(Exception error)
+ {
+ base.Dispose();
+
+ lock (_gate)
+ {
+ _error = error;
+ _hasFailed = true;
+ }
+ }
+
+ public override void OnCompleted()
+ {
+ base.Dispose();
+
+ lock (_gate)
+ {
+ _hasCompleted = true;
+ }
+ }
+
+ public override bool TryMoveNext(out TResult current)
+ {
+ lock (_gate)
+ {
+ if (_hasFailed)
+ {
+ current = default(TResult);
+ _error.Throw();
+ }
+ else
+ {
+ if (_hasCompleted)
+ {
+ if (_done)
+ {
+ current = default(TResult);
+ return false;
+ }
+
+ current = _collector;
+ _done = true;
+ }
+ else
+ {
+ current = _collector;
+
+ try
+ {
+ _collector = _parent._getNewCollector(current);
+ }
+ catch
+ {
+ base.Dispose();
+ throw;
+ }
+ }
+ }
+
+ return true;
+ }
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/CombineLatest.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/CombineLatest.cs
new file mode 100644
index 0000000..2188307
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/CombineLatest.cs
@@ -0,0 +1,1863 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ #region Binary
+
+ class CombineLatest<TFirst, TSecond, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<TFirst> _first;
+ private readonly IObservable<TSecond> _second;
+ private readonly Func<TFirst, TSecond, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<TFirst> first, IObservable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
+ {
+ _first = first;
+ _second = second;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>
+ {
+ private readonly CombineLatest<TFirst, TSecond, TResult> _parent;
+
+ public _(CombineLatest<TFirst, TSecond, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+
+ var fstSubscription = new SingleAssignmentDisposable();
+ var sndSubscription = new SingleAssignmentDisposable();
+
+ var fstO = new F(this, fstSubscription);
+ var sndO = new S(this, sndSubscription);
+
+ fstO.Other = sndO;
+ sndO.Other = fstO;
+
+ fstSubscription.Disposable = _parent._first.SubscribeSafe(fstO);
+ sndSubscription.Disposable = _parent._second.SubscribeSafe(sndO);
+
+ return new CompositeDisposable(fstSubscription, sndSubscription);
+ }
+
+ class F : IObserver<TFirst>
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+ private S _other;
+
+ public F(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ public S Other { set { _other = value; } }
+
+ public bool HasValue { get; private set; }
+ public TFirst Value { get; private set; }
+ public bool Done { get; private set; }
+
+ public void OnNext(TFirst value)
+ {
+ lock (_parent._gate)
+ {
+ HasValue = true;
+ Value = value;
+
+ if (_other.HasValue)
+ {
+ var res = default(TResult);
+ try
+ {
+ res = _parent._parent._resultSelector(value, _other.Value);
+ }
+ catch (Exception ex)
+ {
+ _parent._observer.OnError(ex);
+ _parent.Dispose();
+ return;
+ }
+
+ _parent._observer.OnNext(res);
+ }
+ else if (_other.Done)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ return;
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ Done = true;
+
+ if (_other.Done)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ return;
+ }
+ else
+ {
+ _self.Dispose();
+ }
+ }
+ }
+ }
+
+ class S : IObserver<TSecond>
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+ private F _other;
+
+ public S(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ public F Other { set { _other = value; } }
+
+ public bool HasValue { get; private set; }
+ public TSecond Value { get; private set; }
+ public bool Done { get; private set; }
+
+ public void OnNext(TSecond value)
+ {
+ lock (_parent._gate)
+ {
+ HasValue = true;
+ Value = value;
+
+ if (_other.HasValue)
+ {
+ var res = default(TResult);
+ try
+ {
+ res = _parent._parent._resultSelector(_other.Value, value);
+ }
+ catch (Exception ex)
+ {
+ _parent._observer.OnError(ex);
+ _parent.Dispose();
+ return;
+ }
+
+ _parent._observer.OnNext(res);
+ }
+ else if (_other.Done)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ return;
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ Done = true;
+
+ if (_other.Done)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ return;
+ }
+ else
+ {
+ _self.Dispose();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ #region [3,16]-ary
+
+ /* The following code is generated by a tool checked in to $/.../Source/Tools/CodeGenerators. */
+
+ #region CombineLatest auto-generated code (6/10/2012 7:22:14 PM)
+
+ class CombineLatest<T1, T2, T3, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly Func<T1, T2, T3, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, Func<T1, T2, T3, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(3, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[3];
+ for (int i = 0; i < 3; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly Func<T1, T2, T3, T4, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, Func<T1, T2, T3, T4, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(4, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[4];
+ for (int i = 0; i < 4; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value);
+ }
+ }
+ }
+
+#if !NO_LARGEARITY
+
+ class CombineLatest<T1, T2, T3, T4, T5, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly Func<T1, T2, T3, T4, T5, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, Func<T1, T2, T3, T4, T5, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(5, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[5];
+ for (int i = 0; i < 5; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly Func<T1, T2, T3, T4, T5, T6, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, Func<T1, T2, T3, T4, T5, T6, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(6, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[6];
+ for (int i = 0; i < 6; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, T7, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, Func<T1, T2, T3, T4, T5, T6, T7, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, T7, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, T7, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(7, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+ private CombineLatestObserver<T7> _observer7;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[7];
+ for (int i = 0; i < 7; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new CombineLatestObserver<T7>(_gate, this, 6, subscriptions[6]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value, _observer7.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(8, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+ private CombineLatestObserver<T7> _observer7;
+ private CombineLatestObserver<T8> _observer8;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[8];
+ for (int i = 0; i < 8; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new CombineLatestObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new CombineLatestObserver<T8>(_gate, this, 7, subscriptions[7]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value, _observer7.Value, _observer8.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(9, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+ private CombineLatestObserver<T7> _observer7;
+ private CombineLatestObserver<T8> _observer8;
+ private CombineLatestObserver<T9> _observer9;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[9];
+ for (int i = 0; i < 9; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new CombineLatestObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new CombineLatestObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new CombineLatestObserver<T9>(_gate, this, 8, subscriptions[8]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value, _observer7.Value, _observer8.Value, _observer9.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(10, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+ private CombineLatestObserver<T7> _observer7;
+ private CombineLatestObserver<T8> _observer8;
+ private CombineLatestObserver<T9> _observer9;
+ private CombineLatestObserver<T10> _observer10;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[10];
+ for (int i = 0; i < 10; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new CombineLatestObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new CombineLatestObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new CombineLatestObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new CombineLatestObserver<T10>(_gate, this, 9, subscriptions[9]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value, _observer7.Value, _observer8.Value, _observer9.Value, _observer10.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(11, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+ private CombineLatestObserver<T7> _observer7;
+ private CombineLatestObserver<T8> _observer8;
+ private CombineLatestObserver<T9> _observer9;
+ private CombineLatestObserver<T10> _observer10;
+ private CombineLatestObserver<T11> _observer11;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[11];
+ for (int i = 0; i < 11; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new CombineLatestObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new CombineLatestObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new CombineLatestObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new CombineLatestObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new CombineLatestObserver<T11>(_gate, this, 10, subscriptions[10]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value, _observer7.Value, _observer8.Value, _observer9.Value, _observer10.Value, _observer11.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly IObservable<T12> _source12;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _source12 = source12;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(12, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+ private CombineLatestObserver<T7> _observer7;
+ private CombineLatestObserver<T8> _observer8;
+ private CombineLatestObserver<T9> _observer9;
+ private CombineLatestObserver<T10> _observer10;
+ private CombineLatestObserver<T11> _observer11;
+ private CombineLatestObserver<T12> _observer12;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[12];
+ for (int i = 0; i < 12; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new CombineLatestObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new CombineLatestObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new CombineLatestObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new CombineLatestObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new CombineLatestObserver<T11>(_gate, this, 10, subscriptions[10]);
+ _observer12 = new CombineLatestObserver<T12>(_gate, this, 11, subscriptions[11]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+ subscriptions[11].Disposable = _parent._source12.SubscribeSafe(_observer12);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value, _observer7.Value, _observer8.Value, _observer9.Value, _observer10.Value, _observer11.Value, _observer12.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly IObservable<T12> _source12;
+ private readonly IObservable<T13> _source13;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _source12 = source12;
+ _source13 = source13;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(13, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+ private CombineLatestObserver<T7> _observer7;
+ private CombineLatestObserver<T8> _observer8;
+ private CombineLatestObserver<T9> _observer9;
+ private CombineLatestObserver<T10> _observer10;
+ private CombineLatestObserver<T11> _observer11;
+ private CombineLatestObserver<T12> _observer12;
+ private CombineLatestObserver<T13> _observer13;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[13];
+ for (int i = 0; i < 13; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new CombineLatestObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new CombineLatestObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new CombineLatestObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new CombineLatestObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new CombineLatestObserver<T11>(_gate, this, 10, subscriptions[10]);
+ _observer12 = new CombineLatestObserver<T12>(_gate, this, 11, subscriptions[11]);
+ _observer13 = new CombineLatestObserver<T13>(_gate, this, 12, subscriptions[12]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+ subscriptions[11].Disposable = _parent._source12.SubscribeSafe(_observer12);
+ subscriptions[12].Disposable = _parent._source13.SubscribeSafe(_observer13);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value, _observer7.Value, _observer8.Value, _observer9.Value, _observer10.Value, _observer11.Value, _observer12.Value, _observer13.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly IObservable<T12> _source12;
+ private readonly IObservable<T13> _source13;
+ private readonly IObservable<T14> _source14;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _source12 = source12;
+ _source13 = source13;
+ _source14 = source14;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(14, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+ private CombineLatestObserver<T7> _observer7;
+ private CombineLatestObserver<T8> _observer8;
+ private CombineLatestObserver<T9> _observer9;
+ private CombineLatestObserver<T10> _observer10;
+ private CombineLatestObserver<T11> _observer11;
+ private CombineLatestObserver<T12> _observer12;
+ private CombineLatestObserver<T13> _observer13;
+ private CombineLatestObserver<T14> _observer14;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[14];
+ for (int i = 0; i < 14; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new CombineLatestObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new CombineLatestObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new CombineLatestObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new CombineLatestObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new CombineLatestObserver<T11>(_gate, this, 10, subscriptions[10]);
+ _observer12 = new CombineLatestObserver<T12>(_gate, this, 11, subscriptions[11]);
+ _observer13 = new CombineLatestObserver<T13>(_gate, this, 12, subscriptions[12]);
+ _observer14 = new CombineLatestObserver<T14>(_gate, this, 13, subscriptions[13]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+ subscriptions[11].Disposable = _parent._source12.SubscribeSafe(_observer12);
+ subscriptions[12].Disposable = _parent._source13.SubscribeSafe(_observer13);
+ subscriptions[13].Disposable = _parent._source14.SubscribeSafe(_observer14);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value, _observer7.Value, _observer8.Value, _observer9.Value, _observer10.Value, _observer11.Value, _observer12.Value, _observer13.Value, _observer14.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly IObservable<T12> _source12;
+ private readonly IObservable<T13> _source13;
+ private readonly IObservable<T14> _source14;
+ private readonly IObservable<T15> _source15;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, IObservable<T15> source15, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _source12 = source12;
+ _source13 = source13;
+ _source14 = source14;
+ _source15 = source15;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(15, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+ private CombineLatestObserver<T7> _observer7;
+ private CombineLatestObserver<T8> _observer8;
+ private CombineLatestObserver<T9> _observer9;
+ private CombineLatestObserver<T10> _observer10;
+ private CombineLatestObserver<T11> _observer11;
+ private CombineLatestObserver<T12> _observer12;
+ private CombineLatestObserver<T13> _observer13;
+ private CombineLatestObserver<T14> _observer14;
+ private CombineLatestObserver<T15> _observer15;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[15];
+ for (int i = 0; i < 15; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new CombineLatestObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new CombineLatestObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new CombineLatestObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new CombineLatestObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new CombineLatestObserver<T11>(_gate, this, 10, subscriptions[10]);
+ _observer12 = new CombineLatestObserver<T12>(_gate, this, 11, subscriptions[11]);
+ _observer13 = new CombineLatestObserver<T13>(_gate, this, 12, subscriptions[12]);
+ _observer14 = new CombineLatestObserver<T14>(_gate, this, 13, subscriptions[13]);
+ _observer15 = new CombineLatestObserver<T15>(_gate, this, 14, subscriptions[14]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+ subscriptions[11].Disposable = _parent._source12.SubscribeSafe(_observer12);
+ subscriptions[12].Disposable = _parent._source13.SubscribeSafe(_observer13);
+ subscriptions[13].Disposable = _parent._source14.SubscribeSafe(_observer14);
+ subscriptions[14].Disposable = _parent._source15.SubscribeSafe(_observer15);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value, _observer7.Value, _observer8.Value, _observer9.Value, _observer10.Value, _observer11.Value, _observer12.Value, _observer13.Value, _observer14.Value, _observer15.Value);
+ }
+ }
+ }
+
+ class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly IObservable<T12> _source12;
+ private readonly IObservable<T13> _source13;
+ private readonly IObservable<T14> _source14;
+ private readonly IObservable<T15> _source15;
+ private readonly IObservable<T16> _source16;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> _resultSelector;
+
+ public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, IObservable<T15> source15, IObservable<T16> source16, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _source12 = source12;
+ _source13 = source13;
+ _source14 = source14;
+ _source15 = source15;
+ _source16 = source16;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : CombineLatestSink<TResult>
+ {
+ private readonly CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> _parent;
+
+ public _(CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(16, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CombineLatestObserver<T1> _observer1;
+ private CombineLatestObserver<T2> _observer2;
+ private CombineLatestObserver<T3> _observer3;
+ private CombineLatestObserver<T4> _observer4;
+ private CombineLatestObserver<T5> _observer5;
+ private CombineLatestObserver<T6> _observer6;
+ private CombineLatestObserver<T7> _observer7;
+ private CombineLatestObserver<T8> _observer8;
+ private CombineLatestObserver<T9> _observer9;
+ private CombineLatestObserver<T10> _observer10;
+ private CombineLatestObserver<T11> _observer11;
+ private CombineLatestObserver<T12> _observer12;
+ private CombineLatestObserver<T13> _observer13;
+ private CombineLatestObserver<T14> _observer14;
+ private CombineLatestObserver<T15> _observer15;
+ private CombineLatestObserver<T16> _observer16;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[16];
+ for (int i = 0; i < 16; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new CombineLatestObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new CombineLatestObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new CombineLatestObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new CombineLatestObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new CombineLatestObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new CombineLatestObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new CombineLatestObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new CombineLatestObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new CombineLatestObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new CombineLatestObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new CombineLatestObserver<T11>(_gate, this, 10, subscriptions[10]);
+ _observer12 = new CombineLatestObserver<T12>(_gate, this, 11, subscriptions[11]);
+ _observer13 = new CombineLatestObserver<T13>(_gate, this, 12, subscriptions[12]);
+ _observer14 = new CombineLatestObserver<T14>(_gate, this, 13, subscriptions[13]);
+ _observer15 = new CombineLatestObserver<T15>(_gate, this, 14, subscriptions[14]);
+ _observer16 = new CombineLatestObserver<T16>(_gate, this, 15, subscriptions[15]);
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+ subscriptions[11].Disposable = _parent._source12.SubscribeSafe(_observer12);
+ subscriptions[12].Disposable = _parent._source13.SubscribeSafe(_observer13);
+ subscriptions[13].Disposable = _parent._source14.SubscribeSafe(_observer14);
+ subscriptions[14].Disposable = _parent._source15.SubscribeSafe(_observer15);
+ subscriptions[15].Disposable = _parent._source16.SubscribeSafe(_observer16);
+
+ return new CompositeDisposable(subscriptions);
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Value, _observer2.Value, _observer3.Value, _observer4.Value, _observer5.Value, _observer6.Value, _observer7.Value, _observer8.Value, _observer9.Value, _observer10.Value, _observer11.Value, _observer12.Value, _observer13.Value, _observer14.Value, _observer15.Value, _observer16.Value);
+ }
+ }
+ }
+
+#endif
+
+ #endregion
+
+ #region Helpers for n-ary overloads
+
+ interface ICombineLatest
+ {
+ void Next(int index);
+ void Fail(Exception error);
+ void Done(int index);
+ }
+
+ abstract class CombineLatestSink<TResult> : Sink<TResult>, ICombineLatest
+ {
+ protected readonly object _gate;
+
+ private bool _hasValueAll;
+ private readonly bool[] _hasValue;
+ private readonly bool[] _isDone;
+
+ public CombineLatestSink(int arity, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _gate = new object();
+
+ _hasValue = new bool[arity];
+ _isDone = new bool[arity];
+ }
+
+ public void Next(int index)
+ {
+ if (!_hasValueAll)
+ {
+ _hasValue[index] = true;
+
+ var hasValueAll = true;
+ foreach (var hasValue in _hasValue)
+ {
+ if (!hasValue)
+ {
+ hasValueAll = false;
+ break;
+ }
+ }
+
+ _hasValueAll = hasValueAll;
+ }
+
+ if (_hasValueAll)
+ {
+ var res = default(TResult);
+ try
+ {
+ res = GetResult();
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(res);
+ }
+ else
+ {
+ var allOthersDone = true;
+ for (int i = 0; i < _isDone.Length; i++)
+ {
+ if (i != index && !_isDone[i])
+ {
+ allOthersDone = false;
+ break;
+ }
+ }
+
+ if (allOthersDone)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ protected abstract TResult GetResult();
+
+ public void Fail(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void Done(int index)
+ {
+ _isDone[index] = true;
+
+ var allDone = true;
+ foreach (var isDone in _isDone)
+ {
+ if (!isDone)
+ {
+ allDone = false;
+ break;
+ }
+ }
+
+ if (allDone)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ return;
+ }
+ }
+ }
+
+ class CombineLatestObserver<T> : IObserver<T>
+ {
+ private readonly object _gate;
+ private readonly ICombineLatest _parent;
+ private readonly int _index;
+ private readonly IDisposable _self;
+ private T _value;
+
+ public CombineLatestObserver(object gate, ICombineLatest parent, int index, IDisposable self)
+ {
+ _gate = gate;
+ _parent = parent;
+ _index = index;
+ _self = self;
+ }
+
+ public T Value
+ {
+ get { return _value; }
+ }
+
+ public void OnNext(T value)
+ {
+ lock (_gate)
+ {
+ _value = value;
+ _parent.Next(_index);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ _self.Dispose();
+
+ lock (_gate)
+ {
+ _parent.Fail(error);
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _self.Dispose();
+
+ lock (_gate)
+ {
+ _parent.Done(_index);
+ }
+ }
+ }
+
+ #endregion
+
+ #endregion
+
+ #region N-ary
+
+ class CombineLatest<TSource, TResult> : Producer<TResult>
+ {
+ private readonly IEnumerable<IObservable<TSource>> _sources;
+ private readonly Func<IList<TSource>, TResult> _resultSelector;
+
+ public CombineLatest(IEnumerable<IObservable<TSource>> sources, Func<IList<TSource>, TResult> resultSelector)
+ {
+ _sources = sources;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>
+ {
+ private readonly CombineLatest<TSource, TResult> _parent;
+
+ public _(CombineLatest<TSource, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private bool[] _hasValue;
+ private bool _hasValueAll;
+ private List<TSource> _values;
+ private bool[] _isDone;
+ private IDisposable[] _subscriptions;
+
+ public IDisposable Run()
+ {
+ var srcs = _parent._sources.ToArray();
+
+ var N = srcs.Length;
+
+ _hasValue = new bool[N];
+ _hasValueAll = false;
+
+ _values = new List<TSource>(N);
+ for (int i = 0; i < N; i++)
+ _values.Add(default(TSource));
+
+ _isDone = new bool[N];
+
+ _subscriptions = new IDisposable[N];
+
+ _gate = new object();
+
+ for (int i = 0; i < N; i++)
+ {
+ var j = i;
+
+ var d = new SingleAssignmentDisposable();
+ _subscriptions[j] = d;
+
+ var o = new O(this, j);
+ d.Disposable = srcs[j].SubscribeSafe(o);
+ }
+
+ return new CompositeDisposable(_subscriptions);
+ }
+
+ private void OnNext(int index, TSource value)
+ {
+ lock (_gate)
+ {
+ _values[index] = value;
+
+ _hasValue[index] = true;
+
+ if (_hasValueAll || (_hasValueAll = _hasValue.All(Stubs<bool>.I)))
+ {
+ var res = default(TResult);
+ try
+ {
+ res = _parent._resultSelector(new ReadOnlyCollection<TSource>(_values));
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ _observer.OnNext(res);
+ }
+ else if (_isDone.Where((x, i) => i != index).All(Stubs<bool>.I))
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ return;
+ }
+ }
+ }
+
+ private void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ private void OnCompleted(int index)
+ {
+ lock (_gate)
+ {
+ _isDone[index] = true;
+
+ if (_isDone.All(Stubs<bool>.I))
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ return;
+ }
+ else
+ {
+ _subscriptions[index].Dispose();
+ }
+ }
+ }
+
+ class O : IObserver<TSource>
+ {
+ private readonly _ _parent;
+ private readonly int _index;
+
+ public O(_ parent, int index)
+ {
+ _parent = parent;
+ _index = index;
+ }
+
+ public void OnNext(TSource value)
+ {
+ _parent.OnNext(_index, value);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.OnError(error);
+ }
+
+ public void OnCompleted()
+ {
+ _parent.OnCompleted(_index);
+ }
+ }
+ }
+ }
+
+ #endregion
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Concat.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Concat.cs
new file mode 100644
index 0000000..5a9b2e4
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Concat.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Concat<TSource> : Producer<TSource>, IConcatenatable<TSource>
+ {
+ private readonly IEnumerable<IObservable<TSource>> _sources;
+
+ public Concat(IEnumerable<IObservable<TSource>> sources)
+ {
+ _sources = sources;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return sink.Run(_sources);
+ }
+
+ public IEnumerable<IObservable<TSource>> GetSources()
+ {
+ return _sources;
+ }
+
+ class _ : ConcatSink<TSource>
+ {
+ public _(IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public override void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public override void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Contains.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Contains.cs
new file mode 100644
index 0000000..b26e2d4
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Contains.cs
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Contains<TSource> : Producer<bool>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly TSource _value;
+ private readonly IEqualityComparer<TSource> _comparer;
+
+ public Contains(IObservable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
+ {
+ _source = source;
+ _value = value;
+ _comparer = comparer;
+ }
+
+ protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<bool>, IObserver<TSource>
+ {
+ private readonly Contains<TSource> _parent;
+
+ public _(Contains<TSource> parent, IObserver<bool> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var res = false;
+ try
+ {
+ res = _parent._comparer.Equals(value, _parent._value);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (res)
+ {
+ base._observer.OnNext(true);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(false);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Count.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Count.cs
new file mode 100644
index 0000000..7432816
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Count.cs
@@ -0,0 +1,124 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Count<TSource> : Producer<int>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+
+ public Count(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ public Count(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ _source = source;
+ _predicate = predicate;
+ }
+
+ protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_predicate == null)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new π(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<int>, IObserver<TSource>
+ {
+ private int _count;
+
+ public _(IObserver<int> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _count = 0;
+ }
+
+ public void OnNext(TSource value)
+ {
+ try
+ {
+ checked
+ {
+ _count++;
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_count);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class π : Sink<int>, IObserver<TSource>
+ {
+ private readonly Count<TSource> _parent;
+ private int _count;
+
+ public π(Count<TSource> parent, IObserver<int> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _count = 0;
+ }
+
+ public void OnNext(TSource value)
+ {
+ try
+ {
+ checked
+ {
+ if (_parent._predicate(value))
+ _count++;
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_count);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DefaultIfEmpty.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DefaultIfEmpty.cs
new file mode 100644
index 0000000..ed4bb89
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DefaultIfEmpty.cs
@@ -0,0 +1,60 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class DefaultIfEmpty<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly TSource _defaultValue;
+
+ public DefaultIfEmpty(IObservable<TSource> source, TSource defaultValue)
+ {
+ _source = source;
+ _defaultValue = defaultValue;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly DefaultIfEmpty<TSource> _parent;
+ private bool _found;
+
+ public _(DefaultIfEmpty<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _found = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ _found = true;
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_found)
+ base._observer.OnNext(_parent._defaultValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Defer.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Defer.cs
new file mode 100644
index 0000000..ba3dcc4
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Defer.cs
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Defer<TValue> : Producer<TValue>, IEvaluatableObservable<TValue>
+ {
+ private readonly Func<IObservable<TValue>> _observableFactory;
+
+ public Defer(Func<IObservable<TValue>> observableFactory)
+ {
+ _observableFactory = observableFactory;
+ }
+
+ protected override IDisposable Run(IObserver<TValue> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ public IObservable<TValue> Eval()
+ {
+ return _observableFactory();
+ }
+
+ class _ : Sink<TValue>, IObserver<TValue>
+ {
+ private readonly Defer<TValue> _parent;
+
+ public _(Defer<TValue> parent, IObserver<TValue> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var result = default(IObservable<TValue>);
+ try
+ {
+ result = _parent.Eval();
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ return result.SubscribeSafe(this);
+ }
+
+ public void OnNext(TValue value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Delay.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Delay.cs
new file mode 100644
index 0000000..3e2cbba
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Delay.cs
@@ -0,0 +1,768 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Threading;
+
+#if NO_SEMAPHORE
+using System.Reactive.Threading;
+#endif
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Delay<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly TimeSpan? _dueTimeR;
+ private readonly DateTimeOffset? _dueTimeA;
+ private readonly IScheduler _scheduler;
+
+ public Delay(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ _source = source;
+ _dueTimeR = dueTime;
+ _scheduler = scheduler;
+ }
+
+ public Delay(IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
+ {
+ _source = source;
+ _dueTimeA = dueTime;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_scheduler.AsLongRunning() != null)
+ {
+ var sink = new λ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Delay<TSource> _parent;
+
+ public _(Delay<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private IScheduler _scheduler;
+ private IDisposable _sourceSubscription;
+ private SerialDisposable _cancelable;
+ private TimeSpan _delay;
+ private IStopwatch _watch;
+
+ private object _gate;
+ private bool _ready;
+ private bool _active;
+ private bool _running;
+ private Queue<System.Reactive.TimeInterval<TSource>> _queue;
+ private bool _hasCompleted;
+ private TimeSpan _completeAt;
+ private bool _hasFailed;
+ private Exception _exception;
+
+ public IDisposable Run()
+ {
+ _scheduler = _parent._scheduler;
+
+ _cancelable = new SerialDisposable();
+
+ _gate = new object();
+ _active = false;
+ _running = false;
+ _queue = new Queue<System.Reactive.TimeInterval<TSource>>();
+ _hasCompleted = false;
+ _completeAt = default(TimeSpan);
+ _hasFailed = false;
+ _exception = default(Exception);
+
+ _watch = _scheduler.StartStopwatch();
+
+ if (_parent._dueTimeA.HasValue)
+ {
+ _ready = false;
+
+ var dueTimeA = _parent._dueTimeA.Value;
+ _cancelable.Disposable = _scheduler.Schedule(dueTimeA, Start);
+ }
+ else
+ {
+ _ready = true;
+
+ var dueTimeR = _parent._dueTimeR.Value;
+ _delay = Scheduler.Normalize(dueTimeR);
+ }
+
+ var sourceSubscription = new SingleAssignmentDisposable();
+ _sourceSubscription = sourceSubscription;
+ sourceSubscription.Disposable = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(_sourceSubscription, _cancelable);
+ }
+
+ private void Start()
+ {
+ var next = default(TimeSpan);
+ var shouldRun = false;
+
+ lock (_gate)
+ {
+ _delay = _watch.Elapsed;
+
+ var oldQueue = _queue;
+ _queue = new Queue<Reactive.TimeInterval<TSource>>();
+
+ if (oldQueue.Count > 0)
+ {
+ next = oldQueue.Peek().Interval;
+
+ while (oldQueue.Count > 0)
+ {
+ var item = oldQueue.Dequeue();
+ _queue.Enqueue(new Reactive.TimeInterval<TSource>(item.Value, item.Interval.Add(_delay)));
+ }
+
+ shouldRun = true;
+ _active = true;
+ }
+
+ _ready = true;
+ }
+
+ if (shouldRun)
+ {
+ _cancelable.Disposable = _scheduler.Schedule(next, DrainQueue);
+ }
+ }
+
+ public void OnNext(TSource value)
+ {
+ var next = _watch.Elapsed.Add(_delay);
+ var shouldRun = false;
+
+ lock (_gate)
+ {
+ _queue.Enqueue(new System.Reactive.TimeInterval<TSource>(value, next));
+
+ shouldRun = _ready && !_active;
+ _active = true;
+ }
+
+ if (shouldRun)
+ {
+ _cancelable.Disposable = _scheduler.Schedule(_delay, DrainQueue);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ _sourceSubscription.Dispose();
+
+ var shouldRun = false;
+
+ lock (_gate)
+ {
+ _queue.Clear();
+
+ _exception = error;
+ _hasFailed = true;
+
+ shouldRun = !_running;
+ }
+
+ if (shouldRun)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _sourceSubscription.Dispose();
+
+ var next = _watch.Elapsed.Add(_delay);
+ var shouldRun = false;
+
+ lock (_gate)
+ {
+ _completeAt = next;
+ _hasCompleted = true;
+
+ shouldRun = _ready && !_active;
+ _active = true;
+ }
+
+ if (shouldRun)
+ {
+ _cancelable.Disposable = _scheduler.Schedule(_delay, DrainQueue);
+ }
+ }
+
+ private void DrainQueue(Action<TimeSpan> recurse)
+ {
+ lock (_gate)
+ {
+ if (_hasFailed)
+ return;
+ _running = true;
+ }
+
+ //
+ // The shouldYield flag was added to address TFS 487881: "Delay can be unfair". In the old
+ // implementation, the loop below kept running while there was work for immediate dispatch,
+ // potentially causing a long running work item on the target scheduler. With the addition
+ // of long-running scheduling in Rx v2.0, we can check whether the scheduler supports this
+ // interface and perform different processing (see λ). To reduce the code churn in the old
+ // loop code here, we set the shouldYield flag to true after the first dispatch iteration,
+ // in order to break from the loop and enter the recursive scheduling path.
+ //
+ var shouldYield = false;
+
+ while (true)
+ {
+ var hasFailed = false;
+ var error = default(Exception);
+
+ var hasValue = false;
+ var value = default(TSource);
+ var hasCompleted = false;
+
+ var shouldRecurse = false;
+ var recurseDueTime = default(TimeSpan);
+
+ lock (_gate)
+ {
+ if (_hasFailed)
+ {
+ error = _exception;
+ hasFailed = true;
+ _running = false;
+ }
+ else
+ {
+ var now = _watch.Elapsed;
+
+ if (_queue.Count > 0)
+ {
+ var nextDue = _queue.Peek().Interval;
+
+ if (nextDue.CompareTo(now) <= 0 && !shouldYield)
+ {
+ value = _queue.Dequeue().Value;
+ hasValue = true;
+ }
+ else
+ {
+ shouldRecurse = true;
+ recurseDueTime = Scheduler.Normalize(nextDue.Subtract(now));
+ _running = false;
+ }
+ }
+ else if (_hasCompleted)
+ {
+ if (_completeAt.CompareTo(now) <= 0 && !shouldYield)
+ {
+ hasCompleted = true;
+ }
+ else
+ {
+ shouldRecurse = true;
+ recurseDueTime = Scheduler.Normalize(_completeAt.Subtract(now));
+ _running = false;
+ }
+ }
+ else
+ {
+ _running = false;
+ _active = false;
+ }
+ }
+ } /* lock (_gate) */
+
+ if (hasValue)
+ {
+ base._observer.OnNext(value);
+ shouldYield = true;
+ }
+ else
+ {
+ if (hasCompleted)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ else if (hasFailed)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ else if (shouldRecurse)
+ {
+ recurse(recurseDueTime);
+ }
+
+ return;
+ }
+ } /* while (true) */
+ }
+ }
+
+ class λ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Delay<TSource> _parent;
+
+ public λ(Delay<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private IDisposable _sourceSubscription;
+ private SerialDisposable _cancelable;
+ private TimeSpan _delay;
+ private IStopwatch _watch;
+
+ private object _gate;
+#if !NO_CDS
+ private SemaphoreSlim _evt;
+ private CancellationTokenSource _stop;
+#else
+ private Semaphore _evt;
+ private bool _stopped;
+ private ManualResetEvent _stop;
+#endif
+ private Queue<System.Reactive.TimeInterval<TSource>> _queue;
+ private bool _hasCompleted;
+ private TimeSpan _completeAt;
+ private bool _hasFailed;
+ private Exception _exception;
+
+ public IDisposable Run()
+ {
+ _cancelable = new SerialDisposable();
+
+ _gate = new object();
+#if !NO_CDS
+ _evt = new SemaphoreSlim(0);
+#else
+ _evt = new Semaphore(0, int.MaxValue);
+#endif
+ _queue = new Queue<System.Reactive.TimeInterval<TSource>>();
+ _hasCompleted = false;
+ _completeAt = default(TimeSpan);
+ _hasFailed = false;
+ _exception = default(Exception);
+
+ _watch = _parent._scheduler.StartStopwatch();
+
+ if (_parent._dueTimeA.HasValue)
+ {
+ var dueTimeA = _parent._dueTimeA.Value;
+ _cancelable.Disposable = _parent._scheduler.Schedule(dueTimeA, Start);
+ }
+ else
+ {
+ var dueTimeR = _parent._dueTimeR.Value;
+ _delay = Scheduler.Normalize(dueTimeR);
+ ScheduleDrain();
+ }
+
+ var sourceSubscription = new SingleAssignmentDisposable();
+ _sourceSubscription = sourceSubscription;
+ sourceSubscription.Disposable = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(_sourceSubscription, _cancelable);
+ }
+
+ private void Start()
+ {
+ lock (_gate)
+ {
+ _delay = _watch.Elapsed;
+
+ var oldQueue = _queue;
+ _queue = new Queue<Reactive.TimeInterval<TSource>>();
+
+ while (oldQueue.Count > 0)
+ {
+ var item = oldQueue.Dequeue();
+ _queue.Enqueue(new Reactive.TimeInterval<TSource>(item.Value, item.Interval.Add(_delay)));
+ }
+ }
+
+ ScheduleDrain();
+ }
+
+ private void ScheduleDrain()
+ {
+#if !NO_CDS
+ _stop = new CancellationTokenSource();
+ _cancelable.Disposable = Disposable.Create(() => _stop.Cancel());
+#else
+ _stop = new ManualResetEvent(false);
+ _cancelable.Disposable = Disposable.Create(() =>
+ {
+ _stopped = true;
+ _stop.Set();
+ _evt.Release();
+ });
+#endif
+
+ _parent._scheduler.AsLongRunning().ScheduleLongRunning(DrainQueue);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var next = _watch.Elapsed.Add(_delay);
+
+ lock (_gate)
+ {
+ _queue.Enqueue(new System.Reactive.TimeInterval<TSource>(value, next));
+
+ _evt.Release();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ _sourceSubscription.Dispose();
+
+ lock (_gate)
+ {
+ _queue.Clear();
+
+ _exception = error;
+ _hasFailed = true;
+
+ _evt.Release();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _sourceSubscription.Dispose();
+
+ var next = _watch.Elapsed.Add(_delay);
+
+ lock (_gate)
+ {
+ _completeAt = next;
+ _hasCompleted = true;
+
+ _evt.Release();
+ }
+ }
+
+ private void DrainQueue(ICancelable cancel)
+ {
+ while (true)
+ {
+#if !NO_CDS
+ try
+ {
+ _evt.Wait(_stop.Token);
+ }
+ catch (OperationCanceledException)
+ {
+ return;
+ }
+#else
+ _evt.WaitOne();
+ if (_stopped)
+ return;
+#endif
+
+ var hasFailed = false;
+ var error = default(Exception);
+
+ var hasValue = false;
+ var value = default(TSource);
+ var hasCompleted = false;
+
+ var shouldWait = false;
+ var waitTime = default(TimeSpan);
+
+ lock (_gate)
+ {
+ if (_hasFailed)
+ {
+ error = _exception;
+ hasFailed = true;
+ }
+ else
+ {
+ var now = _watch.Elapsed;
+
+ if (_queue.Count > 0)
+ {
+ var next = _queue.Dequeue();
+
+ hasValue = true;
+ value = next.Value;
+
+ var nextDue = next.Interval;
+ if (nextDue.CompareTo(now) > 0)
+ {
+ shouldWait = true;
+ waitTime = Scheduler.Normalize(nextDue.Subtract(now));
+ }
+ }
+ else if (_hasCompleted)
+ {
+ hasCompleted = true;
+
+ if (_completeAt.CompareTo(now) > 0)
+ {
+ shouldWait = true;
+ waitTime = Scheduler.Normalize(_completeAt.Subtract(now));
+ }
+ }
+ }
+ } /* lock (_gate) */
+
+ if (shouldWait)
+ {
+#if !NO_CDS
+ var timer = new ManualResetEventSlim();
+ _parent._scheduler.Schedule(waitTime, () => { timer.Set(); });
+
+ try
+ {
+ timer.Wait(_stop.Token);
+ }
+ catch (OperationCanceledException)
+ {
+ return;
+ }
+#else
+ var timer = new ManualResetEvent(false);
+ _parent._scheduler.Schedule(waitTime, () => { timer.Set(); });
+ if (WaitHandle.WaitAny(new[] { timer, _stop }) == 1)
+ return;
+#endif
+ }
+
+ if (hasValue)
+ {
+ base._observer.OnNext(value);
+ }
+ else
+ {
+ if (hasCompleted)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ else if (hasFailed)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ class Delay<TSource, TDelay> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly IObservable<TDelay> _subscriptionDelay;
+ private readonly Func<TSource, IObservable<TDelay>> _delaySelector;
+
+ public Delay(IObservable<TSource> source, IObservable<TDelay> subscriptionDelay, Func<TSource, IObservable<TDelay>> delaySelector)
+ {
+ _source = source;
+ _subscriptionDelay = subscriptionDelay;
+ _delaySelector = delaySelector;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Delay<TSource, TDelay> _parent;
+
+ public _(Delay<TSource, TDelay> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private CompositeDisposable _delays;
+ private object _gate;
+ private bool _atEnd;
+ private SerialDisposable _subscription;
+
+ public IDisposable Run()
+ {
+ _delays = new CompositeDisposable();
+ _gate = new object();
+ _atEnd = false;
+ _subscription = new SerialDisposable();
+
+ if (_parent._subscriptionDelay == null)
+ {
+ Start();
+ }
+ else
+ {
+ _subscription.Disposable = _parent._subscriptionDelay.SubscribeSafe(new σ(this));
+ }
+
+ return new CompositeDisposable(_subscription, _delays);
+ }
+
+ private void Start()
+ {
+ _subscription.Disposable = _parent._source.SubscribeSafe(this);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var delay = default(IObservable<TDelay>);
+ try
+ {
+ delay = _parent._delaySelector(value);
+ }
+ catch (Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ return;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ _delays.Add(d);
+ d.Disposable = delay.SubscribeSafe(new δ(this, value, d));
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ _atEnd = true;
+ _subscription.Dispose();
+
+ CheckDone();
+ }
+ }
+
+ private void CheckDone()
+ {
+ if (_atEnd && _delays.Count == 0)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class σ : IObserver<TDelay>
+ {
+ private readonly _ _parent;
+
+ public σ(_ parent)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TDelay value)
+ {
+ _parent.Start();
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ _parent.Start();
+ }
+ }
+
+ class δ : IObserver<TDelay>
+ {
+ private readonly _ _parent;
+ private readonly TSource _value;
+ private readonly IDisposable _self;
+
+ public δ(_ parent, TSource value, IDisposable self)
+ {
+ _parent = parent;
+ _value = value;
+ _self = self;
+ }
+
+ public void OnNext(TDelay value)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnNext(_value);
+
+ _parent._delays.Remove(_self);
+ _parent.CheckDone();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnNext(_value);
+
+ _parent._delays.Remove(_self);
+ _parent.CheckDone();
+ }
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DelaySubscription.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DelaySubscription.cs
new file mode 100644
index 0000000..c6a05cc
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DelaySubscription.cs
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class DelaySubscription<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly DateTimeOffset? _dueTimeA;
+ private readonly TimeSpan? _dueTimeR;
+ private readonly IScheduler _scheduler;
+
+ public DelaySubscription(IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
+ {
+ _source = source;
+ _dueTimeA = dueTime;
+ _scheduler = scheduler;
+ }
+
+ public DelaySubscription(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ _source = source;
+ _dueTimeR = dueTime;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+
+ if (_dueTimeA.HasValue)
+ {
+ return _scheduler.Schedule(sink, _dueTimeA.Value, Subscribe);
+ }
+ else
+ {
+ return _scheduler.Schedule(sink, _dueTimeR.Value, Subscribe);
+ }
+ }
+
+ private IDisposable Subscribe(IScheduler _, _ sink)
+ {
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ public _(IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Dematerialize.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Dematerialize.cs
new file mode 100644
index 0000000..112b156
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Dematerialize.cs
@@ -0,0 +1,63 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Dematerialize<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<Notification<TSource>> _source;
+
+ public Dematerialize(IObservable<Notification<TSource>> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<Notification<TSource>>
+ {
+ public _(IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public void OnNext(Notification<TSource> value)
+ {
+ switch (value.Kind)
+ {
+ case NotificationKind.OnNext:
+ base._observer.OnNext(value.Value);
+ break;
+ case NotificationKind.OnError:
+ base._observer.OnError(value.Exception);
+ base.Dispose();
+ break;
+ case NotificationKind.OnCompleted:
+ base._observer.OnCompleted();
+ base.Dispose();
+ break;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Distinct.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Distinct.cs
new file mode 100644
index 0000000..af20277
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Distinct.cs
@@ -0,0 +1,75 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Distinct<TSource, TKey> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TKey> _keySelector;
+ private readonly IEqualityComparer<TKey> _comparer;
+
+ public Distinct(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+ _source = source;
+ _keySelector = keySelector;
+ _comparer = comparer;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Distinct<TSource, TKey> _parent;
+ private HashSet<TKey> _hashSet;
+
+ public _(Distinct<TSource, TKey> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _hashSet = new HashSet<TKey>(_parent._comparer);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var key = default(TKey);
+ var hasAdded = false;
+ try
+ {
+ key = _parent._keySelector(value);
+ hasAdded = _hashSet.Add(key);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ if (hasAdded)
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DistinctUntilChanged.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DistinctUntilChanged.cs
new file mode 100644
index 0000000..10c7923
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DistinctUntilChanged.cs
@@ -0,0 +1,94 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class DistinctUntilChanged<TSource, TKey> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TKey> _keySelector;
+ private readonly IEqualityComparer<TKey> _comparer;
+
+ public DistinctUntilChanged(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+ _source = source;
+ _keySelector = keySelector;
+ _comparer = comparer;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly DistinctUntilChanged<TSource, TKey> _parent;
+ private TKey _currentKey;
+ private bool _hasCurrentKey;
+
+ public _(DistinctUntilChanged<TSource, TKey> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _currentKey = default(TKey);
+ _hasCurrentKey = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var key = default(TKey);
+ try
+ {
+ key = _parent._keySelector(value);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ var comparerEquals = false;
+ if (_hasCurrentKey)
+ {
+ try
+ {
+ comparerEquals = _parent._comparer.Equals(_currentKey, key);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+ }
+
+ if (!_hasCurrentKey || !comparerEquals)
+ {
+ _hasCurrentKey = true;
+ _currentKey = key;
+ base._observer.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Do.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Do.cs
new file mode 100644
index 0000000..2f73cfa
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Do.cs
@@ -0,0 +1,92 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Do<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Action<TSource> _onNext;
+ private readonly Action<Exception> _onError;
+ private readonly Action _onCompleted;
+
+ public Do(IObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted)
+ {
+ _source = source;
+ _onNext = onNext;
+ _onError = onError;
+ _onCompleted = onCompleted;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Do<TSource> _parent;
+
+ public _(Do<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ try
+ {
+ _parent._onNext(value);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ try
+ {
+ _parent._onError(error);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ try
+ {
+ _parent._onCompleted();
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DoWhile.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DoWhile.cs
new file mode 100644
index 0000000..3ef40eb
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DoWhile.cs
@@ -0,0 +1,54 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class DoWhile<TSource> : Producer<TSource>, IConcatenatable<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<bool> _condition;
+
+ public DoWhile(IObservable<TSource> source, Func<bool> condition)
+ {
+ _condition = condition;
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return sink.Run(GetSources());
+ }
+
+ public IEnumerable<IObservable<TSource>> GetSources()
+ {
+ yield return _source;
+ while (_condition())
+ yield return _source;
+ }
+
+ class _ : ConcatSink<TSource>
+ {
+ public _(IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public override void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public override void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ElementAt.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ElementAt.cs
new file mode 100644
index 0000000..b2b1212
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ElementAt.cs
@@ -0,0 +1,75 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class ElementAt<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly int _index;
+ private readonly bool _throwOnEmpty;
+
+ public ElementAt(IObservable<TSource> source, int index, bool throwOnEmpty)
+ {
+ _source = source;
+ _index = index;
+ _throwOnEmpty = throwOnEmpty;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly ElementAt<TSource> _parent;
+ private int _i;
+
+ public _(ElementAt<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _i = _parent._index;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_i == 0)
+ {
+ base._observer.OnNext(value);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+
+ _i--;
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_parent._throwOnEmpty)
+ {
+ base._observer.OnError(new ArgumentOutOfRangeException("index"));
+ }
+ else
+ {
+ base._observer.OnNext(default(TSource));
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Empty.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Empty.cs
new file mode 100644
index 0000000..42c7241
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Empty.cs
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Empty<TResult> : Producer<TResult>
+ {
+ private readonly IScheduler _scheduler;
+
+ public Empty(IScheduler scheduler)
+ {
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>
+ {
+ private readonly Empty<TResult> _parent;
+
+ public _(Empty<TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ return _parent._scheduler.Schedule(Invoke);
+ }
+
+ private void Invoke()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Finally.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Finally.cs
new file mode 100644
index 0000000..ca9a5d8
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Finally.cs
@@ -0,0 +1,73 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Finally<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Action _finallyAction;
+
+ public Finally(IObservable<TSource> source, Action finallyAction)
+ {
+ _source = source;
+ _finallyAction = finallyAction;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Finally<TSource> _parent;
+
+ public _(Finally<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var subscription = _parent._source.SubscribeSafe(this);
+
+ return Disposable.Create(() =>
+ {
+ try
+ {
+ subscription.Dispose();
+ }
+ finally
+ {
+ _parent._finallyAction();
+ }
+ });
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FirstAsync.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FirstAsync.cs
new file mode 100644
index 0000000..8d8bba7
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FirstAsync.cs
@@ -0,0 +1,132 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class FirstAsync<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+ private readonly bool _throwOnEmpty;
+
+ public FirstAsync(IObservable<TSource> source, Func<TSource, bool> predicate, bool throwOnEmpty)
+ {
+ _source = source;
+ _predicate = predicate;
+ _throwOnEmpty = throwOnEmpty;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_predicate != null)
+ {
+ var sink = new π(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly FirstAsync<TSource> _parent;
+
+ public _(FirstAsync<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_parent._throwOnEmpty)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(default(TSource));
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+
+ class π : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly FirstAsync<TSource> _parent;
+
+ public π(FirstAsync<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var b = false;
+
+ try
+ {
+ b = _parent._predicate(value);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (b)
+ {
+ base._observer.OnNext(value);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_parent._throwOnEmpty)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_MATCHING_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(default(TSource));
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/For.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/For.cs
new file mode 100644
index 0000000..85b9e03
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/For.cs
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class For<TSource, TResult> : Producer<TResult>, IConcatenatable<TResult>
+ {
+ private readonly IEnumerable<TSource> _source;
+ private readonly Func<TSource, IObservable<TResult>> _resultSelector;
+
+ public For(IEnumerable<TSource> source, Func<TSource, IObservable<TResult>> resultSelector)
+ {
+ _source = source;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return sink.Run(GetSources());
+ }
+
+ public IEnumerable<IObservable<TResult>> GetSources()
+ {
+ foreach (var item in _source)
+ yield return _resultSelector(item);
+ }
+
+ class _ : ConcatSink<TResult>
+ {
+ public _(IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public override void OnNext(TResult value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public override void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ForEach.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ForEach.cs
new file mode 100644
index 0000000..38e112d
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ForEach.cs
@@ -0,0 +1,122 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class ForEach<TSource>
+ {
+ public class _ : IObserver<TSource>
+ {
+ private readonly Action<TSource> _onNext;
+ private readonly Action _done;
+
+ private Exception _exception;
+ private int _stopped;
+
+ public _(Action<TSource> onNext, Action done)
+ {
+ _onNext = onNext;
+ _done = done;
+
+ _stopped = 0;
+ }
+
+ public Exception Error
+ {
+ get { return _exception; }
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_stopped == 0)
+ {
+ try
+ {
+ _onNext(value);
+ }
+ catch (Exception ex)
+ {
+ OnError(ex);
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ if (Interlocked.Exchange(ref _stopped, 1) == 0)
+ {
+ _exception = error;
+ _done();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ if (Interlocked.Exchange(ref _stopped, 1) == 0)
+ {
+ _done();
+ }
+ }
+ }
+
+ public class τ : IObserver<TSource>
+ {
+ private readonly Action<TSource, int> _onNext;
+ private readonly Action _done;
+
+ private int _index;
+ private Exception _exception;
+ private int _stopped;
+
+ public τ(Action<TSource, int> onNext, Action done)
+ {
+ _onNext = onNext;
+ _done = done;
+
+ _index = 0;
+ _stopped = 0;
+ }
+
+ public Exception Error
+ {
+ get { return _exception; }
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_stopped == 0)
+ {
+ try
+ {
+ _onNext(value, checked(_index++));
+ }
+ catch (Exception ex)
+ {
+ OnError(ex);
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ if (Interlocked.Exchange(ref _stopped, 1) == 0)
+ {
+ _exception = error;
+ _done();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ if (Interlocked.Exchange(ref _stopped, 1) == 0)
+ {
+ _done();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FromEvent.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FromEvent.cs
new file mode 100644
index 0000000..82c4348
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FromEvent.cs
@@ -0,0 +1,368 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Diagnostics;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+//
+// BREAKING CHANGE v2 > v1.x - FromEvent[Pattern] now has an implicit SubscribeOn and Publish operation.
+//
+// The free-threaded nature of Rx is key to the performance characteristics of the event processing
+// pipeline. However, in places where we bridge with the external world, this sometimes has negative
+// effects due to thread-affine operations involved. The FromEvent[Pattern] bridges are one such
+// place where we reach out to add and remove operations on events.
+//
+// Consider the following piece of code, assuming Rx v1.x usage:
+//
+// var txt = Observable.FromEventPattern(txtInput, "TextChanged");
+// var res = from term in txt
+// from word in svc.Lookup(term).TakeUntil(txt)
+// select word;
+//
+// This code is flawed for various reasons. Seasoned Rx developers will immediately suggest usage of
+// the Publish operator to share the side-effects of subscribing to the txt sequence, resulting in
+// only one subscription to the event:
+//
+// var txt = Observable.FromEventPattern(txtInput, "TextChanged");
+// var res = txt.Publish(txt_ => from term in txt_
+// from word in svc.Lookup(term).TakeUntil(txt_)
+// select word);
+//
+// Customers are typically confused as to why FromEvent[Pattern] causes multiple handlers to be added
+// to the underlying event. This is in contrast with other From* bridges which involve the use of a
+// subject (e.g. FromAsyncPattern, FromAsync, and ToObservable on Task<T>).
+//
+// But there are more issues with the code fragment above. Upon completion of the svc.Lookup(term)
+// sequence, TakeUntil will unsubscribe from both sequences, causing the unsubscription to happen in
+// the context of the source's OnCompleted, which may be the thread pool. Some thread-affine events
+// don't quite like this. In UI frameworks like WPF and Silverlight, this turns out to be not much of
+// a problem typically, but it's merely an accident things work out. From an e-mail conversion with
+// the WPF/SL/Jupiter experts:
+//
+// "Unfortunately, as I expected, it’s confusing, and implementation details are showing through.
+// The bottom line is that event add/remove should always be done on the right thread.
+//
+// Where events are implemented with compiler-generated code, i.e. MultiCastDelegate, the add/remove
+// will be thread safe/agile. Where events are implemented in custom code, across Wpf/SL/WP/Jupiter,
+// the add/remove are expected to happen on the Dispatcher thread.
+//
+// Jupiter actually has the consistent story here, where all the event add/remove implementations do
+// the thread check. It should still be a “wrong thread” error, though, not an AV.
+//
+// In SL there’s a mix of core events (which do the thread check) and framework events (which use
+// compiler-generated event implementations). So you get an exception if you unhook Button.Loaded
+// from off thread, but you don’t get an exception if you unhook Button.Click.
+//
+// In WPF there’s a similar mix (some events are compiler-generated and some use the EventHandlerStore).
+// But I don’t see any thread safety or thread check in the EventHandlerStore. So while it works, IIUC,
+// it should have race conditions and corruptions."
+//
+// Starting with "Jupiter" (Windows XAML aka "Metro"), checks are added to ensure the add and remove
+// operations for UI events are called from the UI thread. As a result, the dictionary suggest sample
+// code shown above starts to fail. A possible fix is to use SubscribeOnDispatcher:
+//
+// var txt = Observable.FromEventPattern(txtInput, "TextChanged").SubscribeOnDispatcher();
+// var res = from term in txt
+// from word in svc.Lookup(term).TakeUntil(txt)
+// select word;
+//
+// This fix has two problems:
+//
+// 1. Customers often don't quite understand the difference between ObserveOn and SubscribeOn. In fact,
+// we've given guidance that use of the latter is typically indicative of a misunderstanding, and
+// is used rarely. Also, the fragment above would likely be extended with some UI binding code where
+// one needs to use ObserveOnDispatcher, so the combination of both becomes even more confusing.
+//
+// 2. There's a subtle race condition now. Upon receiving a new term from the txt sequence, SelectMany's
+// invocation of the result selector involves TakeUntil subscribing to txt again. However, the use
+// of SubscribeOnDispatcher means the subscription is now happening asynchronously, leaving a time
+// gap between returning from Subscribe and doing the += on the underlying event:
+//
+// (Subscription of TakeUntil to txt)
+// |
+// v
+// txt --------------------------------------------------------------
+// |
+// +-----...----+ (SubscribeOnDispatcher's post of Subscribe)
+// |
+// TextChanged ------"re"---------"rea"-------------"reac"-----"react"----...
+// ^
+// |
+// (where += on the event happens)
+//
+// While this problem is rare and sometimes gets mitigated by accident because code is posting back
+// to e.g. the UI message loop, it's extremely hard to debug when things go wrong.
+//
+// In order to fix this behavior such that code has the expected behavior, we do two things in Rx v2.0:
+//
+// - To solve the cross-thread add/remove handler operations and make them single-thread affine, we
+// now do an implicit SubscribeOn with the SynchronizationContext.Current retrieved eagerly upon
+// calling FromEvent[Pattern]. This goes hand-in-hand with a recommendation:
+//
+// "Always call FromEvent[Pattern] in a place where you'd normally write += and -= operations
+// yourself. Don't inline the creation of a FromEvent[Pattern] object inside a query."
+//
+// This recommendation helps to keep code clean (bridging operations are moved outside queries) and
+// ensures the captured SynchronizationContext is the least surprising one. E.g in the sample code
+// above, the whole query likely lives in a button_Click handler or so.
+//
+// - To solve the time gap issue, we now add implicit Publish behavior with ref-counted behavior. In
+// other words, the new FromEvent[Pattern] is pretty much the same as:
+//
+// Observable_v2.FromEvent[Pattern](<args>)
+// ==
+// Observable_v1.FromEvent[Pattern](<args>).SubscribeOn(SynchronizationContext.Current)
+// .Publish()
+// .RefCount()
+//
+// Overloads to FromEvent[Pattern] allow to specify the scheduler used for the SubscribeOn operation
+// that's taking place internally. When omitted, a SynchronizationContextScheduler will be supplied
+// if a current SynchronizationContext is found. If no current SynchronizationContext is found, the
+// default scheduler is the immediate scheduler, falling back to the free-threaded behavior we had
+// before in v1.x. (See GetSchedulerForCurrentContext in QueryLanguage.Events.cs).
+//
+// Notice a time gap can still occur at the point of the first subscription to the event sequence,
+// or when the ref count fell back to zero. In cases of nested uses of the sequence (such as in the
+// running example here), this is fine because the top-level subscription is kept alive for the whole
+// duration. In other cases, there's already a race condition between the underlying event and the
+// observable wrapper (assuming events are hot). For cold events that have side-effects upon add and
+// remove handler operations, use of Observable.Create is recommended. This should be rather rare,
+// as most events follow the typical MulticastDelegate implementation pattern:
+//
+// public event EventHandler<BarEventArgs> Bar;
+//
+// protected void OnBar(int value)
+// {
+// var bar = Bar;
+// if (bar != null)
+// bar(this, new BarEventArgs(value));
+// }
+//
+// In here, there's already a race between the user hooking up an event handler through the += add
+// operation and the event producer (possibly on a different thread) calling OnBar. It's also worth
+// pointing out that this race condition is migitated by a check in SynchronizationContextScheduler
+// causing synchronous execution in case the caller is already on the target SynchronizationContext.
+// This situation is common when using FromEvent[Pattern] immediately after declaring it, e.g. in
+// the context of a UI event handler.
+//
+// Finally, notice we can't simply connect the event to a Subject<T> upon a FromEvent[Pattern] call,
+// because this would make it impossible to get rid of this one event handler (unless we expose some
+// other means of resource maintenance, e.g. by making the returned object implement IDisposable).
+// Also, this would cause the event producer to see the event's delegate in a non-null state all the
+// time, causing event argument objects to be newed up, possibly sending those into a zero-observer
+// subject (which is opaque to the event producer). Not to mention that the subject would always be
+// rooted by the target event (even when the FromEvent[Pattern] observable wrapper is unreachable).
+//
+namespace System.Reactive.Linq.Observαble
+{
+ class FromEvent<TDelegate, TEventArgs> : ClassicEventProducer<TDelegate, TEventArgs>
+ {
+ private readonly Func<Action<TEventArgs>, TDelegate> _conversion;
+
+ public FromEvent(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ : base(addHandler, removeHandler, scheduler)
+ {
+ }
+
+ public FromEvent(Func<Action<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ : base(addHandler, removeHandler, scheduler)
+ {
+ _conversion = conversion;
+ }
+
+ protected override TDelegate GetHandler(Action<TEventArgs> onNext)
+ {
+ var handler = default(TDelegate);
+
+ if (_conversion == null)
+ {
+ handler = ReflectionUtils.CreateDelegate<TDelegate>(onNext, typeof(Action<TEventArgs>).GetMethod("Invoke"));
+ }
+ else
+ {
+ handler = _conversion(onNext);
+ }
+
+ return handler;
+ }
+ }
+
+ abstract class EventProducer<TDelegate, TArgs> : Producer<TArgs>
+ {
+ private readonly IScheduler _scheduler;
+ private readonly object _gate;
+
+ public EventProducer(IScheduler scheduler)
+ {
+ _scheduler = scheduler;
+ _gate = new object();
+ }
+
+ protected abstract TDelegate GetHandler(Action<TArgs> onNext);
+ protected abstract IDisposable AddHandler(TDelegate handler);
+
+ private Session _session;
+
+ protected override IDisposable Run(IObserver<TArgs> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var connection = default(IDisposable);
+
+ lock (_gate)
+ {
+ //
+ // A session object holds on to a single handler to the underlying event, feeding
+ // into a subject. It also ref counts the number of connections to the subject.
+ //
+ // When the ref count goes back to zero, the event handler is unregistered, and
+ // the session will reach out to reset the _session field to null under the _gate
+ // lock. Future subscriptions will cause a new session to be created.
+ //
+ if (_session == null)
+ _session = new Session(this);
+
+ connection = _session.Connect(observer);
+ }
+
+ return connection;
+ }
+
+ class Session
+ {
+ private readonly EventProducer<TDelegate, TArgs> _parent;
+ private readonly Subject<TArgs> _subject;
+
+ private SingleAssignmentDisposable _removeHandler;
+ private int _count;
+
+ public Session(EventProducer<TDelegate, TArgs> parent)
+ {
+ _parent = parent;
+ _subject = new Subject<TArgs>();
+ }
+
+ public IDisposable Connect(IObserver<TArgs> observer)
+ {
+ /*
+ * CALLERS - Ensure this is called under the lock!
+ *
+ lock (_parent._gate) */
+ {
+ //
+ // We connect the given observer to the subject first, before performing any kind
+ // of initialization which will register an event handler. This is done to ensure
+ // we don't have a time gap between adding the handler and connecting the user's
+ // subject, e.g. when the ImmediateScheduler is used.
+ //
+ // [OK] Use of unsafe Subscribe: called on a known subject implementation.
+ //
+ var connection = _subject.Subscribe/*Unsafe*/(observer);
+
+ if (++_count == 1)
+ {
+ try
+ {
+ Initialize();
+ }
+ catch (Exception exception)
+ {
+ --_count;
+ connection.Dispose();
+
+ observer.OnError(exception);
+ return Disposable.Empty;
+ }
+ }
+
+ return Disposable.Create(() =>
+ {
+ connection.Dispose();
+
+ lock (_parent._gate)
+ {
+ if (--_count == 0)
+ {
+ _parent._scheduler.Schedule(_removeHandler.Dispose);
+ _parent._session = null;
+ }
+ }
+ });
+ }
+ }
+
+ private void Initialize()
+ {
+ /*
+ * CALLERS - Ensure this is called under the lock!
+ *
+ lock (_parent._gate) */
+ {
+ //
+ // When the ref count goes to zero, no-one should be able to perform operations on
+ // the session object anymore, because it gets nulled out.
+ //
+ Debug.Assert(_removeHandler == null);
+ _removeHandler = new SingleAssignmentDisposable();
+
+ //
+ // Conversion code is supposed to be a pure function and shouldn't be run on the
+ // scheduler, but the add handler call should. Notice the scheduler can be the
+ // ImmediateScheduler, causing synchronous invocation. This is the default when
+ // no SynchronizationContext is found (see QueryLanguage.Events.cs and search for
+ // the GetSchedulerForCurrentContext method).
+ //
+ var onNext = _parent.GetHandler(_subject.OnNext);
+ _parent._scheduler.Schedule(onNext, AddHandler);
+ }
+ }
+
+ private IDisposable AddHandler(IScheduler self, TDelegate onNext)
+ {
+ var removeHandler = default(IDisposable);
+ try
+ {
+ removeHandler = _parent.AddHandler(onNext);
+ }
+ catch (Exception exception)
+ {
+ _subject.OnError(exception);
+ return Disposable.Empty;
+ }
+
+ //
+ // We don't propagate the exception to the OnError channel upon Dispose. This is
+ // not possible at this stage, because we've already auto-detached in the base
+ // class Producer implementation. Even if we would switch the OnError and auto-
+ // detach calls, it wouldn't work because the remove handler logic is scheduled
+ // on the given scheduler, causing asynchrony. We can't block waiting for the
+ // remove handler to run on the scheduler.
+ //
+ _removeHandler.Disposable = removeHandler;
+
+ return Disposable.Empty;
+ }
+ }
+ }
+
+ abstract class ClassicEventProducer<TDelegate, TArgs> : EventProducer<TDelegate, TArgs>
+ {
+ private readonly Action<TDelegate> _addHandler;
+ private readonly Action<TDelegate> _removeHandler;
+
+ public ClassicEventProducer(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ : base(scheduler)
+ {
+ _addHandler = addHandler;
+ _removeHandler = removeHandler;
+ }
+
+ protected override IDisposable AddHandler(TDelegate handler)
+ {
+ _addHandler(handler);
+ return Disposable.Create(() => _removeHandler(handler));
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FromEventPattern.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FromEventPattern.cs
new file mode 100644
index 0000000..76da050
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FromEventPattern.cs
@@ -0,0 +1,143 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reflection;
+using System.Threading;
+
+//
+// BREAKING CHANGE v2 > v1.x - FromEvent[Pattern] now has an implicit SubscribeOn and Publish operation.
+//
+// See FromEvent.cs for more information.
+//
+namespace System.Reactive.Linq.Observαble
+{
+ class FromEventPattern
+ {
+ public class τ<TDelegate, TEventArgs> : ClassicEventProducer<TDelegate, EventPattern<TEventArgs>>
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ private readonly Func<EventHandler<TEventArgs>, TDelegate> _conversion;
+
+ public τ(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ : base(addHandler, removeHandler, scheduler)
+ {
+ }
+
+ public τ(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ : base(addHandler, removeHandler, scheduler)
+ {
+ _conversion = conversion;
+ }
+
+ protected override TDelegate GetHandler(Action<EventPattern<TEventArgs>> onNext)
+ {
+ var handler = default(TDelegate);
+
+ if (_conversion == null)
+ {
+ Action<object, TEventArgs> h = (sender, eventArgs) => onNext(new EventPattern<TEventArgs>(sender, eventArgs));
+ handler = ReflectionUtils.CreateDelegate<TDelegate>(h, typeof(Action<object, TEventArgs>).GetMethod("Invoke"));
+ }
+ else
+ {
+ handler = _conversion((sender, eventArgs) => onNext(new EventPattern<TEventArgs>(sender, eventArgs)));
+ }
+
+ return handler;
+ }
+ }
+
+ public class τ<TDelegate, TSender, TEventArgs> : ClassicEventProducer<TDelegate, EventPattern<TSender, TEventArgs>>
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ public τ(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ : base(addHandler, removeHandler, scheduler)
+ {
+ }
+
+ protected override TDelegate GetHandler(Action<EventPattern<TSender, TEventArgs>> onNext)
+ {
+ Action<TSender, TEventArgs> h = (sender, eventArgs) => onNext(new EventPattern<TSender, TEventArgs>(sender, eventArgs));
+ return ReflectionUtils.CreateDelegate<TDelegate>(h, typeof(Action<TSender, TEventArgs>).GetMethod("Invoke"));
+ }
+ }
+
+ public class ρ<TSender, TEventArgs, TResult> : EventProducer<Delegate, TResult>
+ {
+ private readonly object _target;
+ private readonly Type _delegateType;
+ private readonly MethodInfo _addMethod;
+ private readonly MethodInfo _removeMethod;
+ private readonly Func<TSender, TEventArgs, TResult> _getResult;
+#if HAS_WINRT
+ private readonly bool _isWinRT;
+#endif
+
+ public ρ(object target, Type delegateType, MethodInfo addMethod, MethodInfo removeMethod, Func<TSender, TEventArgs, TResult> getResult, bool isWinRT, IScheduler scheduler)
+ : base(scheduler)
+ {
+#if HAS_WINRT
+ _isWinRT = isWinRT;
+#else
+ System.Diagnostics.Debug.Assert(!isWinRT);
+#endif
+ _target = target;
+ _delegateType = delegateType;
+ _addMethod = addMethod;
+ _removeMethod = removeMethod;
+ _getResult = getResult;
+ }
+
+ protected override Delegate GetHandler(Action<TResult> onNext)
+ {
+ Action<TSender, TEventArgs> h = (sender, eventArgs) => onNext(_getResult(sender, eventArgs));
+ return ReflectionUtils.CreateDelegate(_delegateType, h, typeof(Action<TSender, TEventArgs>).GetMethod("Invoke"));
+ }
+
+ protected override IDisposable AddHandler(Delegate handler)
+ {
+ var removeHandler = default(Action);
+
+ try
+ {
+#if HAS_WINRT
+ if (_isWinRT)
+ {
+ var token = _addMethod.Invoke(_target, new object[] { handler });
+ removeHandler = () => _removeMethod.Invoke(_target, new object[] { token });
+ }
+ else
+#endif
+ {
+ _addMethod.Invoke(_target, new object[] { handler });
+ removeHandler = () => _removeMethod.Invoke(_target, new object[] { handler });
+ }
+ }
+ catch (TargetInvocationException tie)
+ {
+ throw tie.InnerException;
+ }
+
+ return Disposable.Create(() =>
+ {
+ try
+ {
+ removeHandler();
+ }
+ catch (TargetInvocationException tie)
+ {
+ throw tie.InnerException;
+ }
+ });
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Generate.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Generate.cs
new file mode 100644
index 0000000..89ef862
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Generate.cs
@@ -0,0 +1,292 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Diagnostics;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Generate<TState, TResult> : Producer<TResult>
+ {
+ private readonly TState _initialState;
+ private readonly Func<TState, bool> _condition;
+ private readonly Func<TState, TState> _iterate;
+ private readonly Func<TState, TResult> _resultSelector;
+ private readonly Func<TState, DateTimeOffset> _timeSelectorA;
+ private readonly Func<TState, TimeSpan> _timeSelectorR;
+ private readonly IScheduler _scheduler;
+
+ public Generate(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, IScheduler scheduler)
+ {
+ _initialState = initialState;
+ _condition = condition;
+ _iterate = iterate;
+ _resultSelector = resultSelector;
+ _scheduler = scheduler;
+ }
+
+ public Generate(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, DateTimeOffset> timeSelector, IScheduler scheduler)
+ {
+ _initialState = initialState;
+ _condition = condition;
+ _iterate = iterate;
+ _resultSelector = resultSelector;
+ _timeSelectorA = timeSelector;
+ _scheduler = scheduler;
+ }
+
+ public Generate(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, TimeSpan> timeSelector, IScheduler scheduler)
+ {
+ _initialState = initialState;
+ _condition = condition;
+ _iterate = iterate;
+ _resultSelector = resultSelector;
+ _timeSelectorR = timeSelector;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_timeSelectorA != null)
+ {
+ var sink = new α(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else if (_timeSelectorR != null)
+ {
+ var sink = new δ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class α : Sink<TResult>
+ {
+ private readonly Generate<TState, TResult> _parent;
+
+ public α(Generate<TState, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private bool _first;
+ private bool _hasResult;
+ private TResult _result;
+
+ public IDisposable Run()
+ {
+ _first = true;
+ _hasResult = false;
+ _result = default(TResult);
+
+ return _parent._scheduler.Schedule(_parent._initialState, InvokeRec);
+ }
+
+ private IDisposable InvokeRec(IScheduler self, TState state)
+ {
+ var time = default(DateTimeOffset);
+
+ if (_hasResult)
+ base._observer.OnNext(_result);
+ try
+ {
+ if (_first)
+ _first = false;
+ else
+ state = _parent._iterate(state);
+ _hasResult = _parent._condition(state);
+ if (_hasResult)
+ {
+ _result = _parent._resultSelector(state);
+ time = _parent._timeSelectorA(state);
+ }
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ if (!_hasResult)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ return self.Schedule(state, time, InvokeRec);
+ }
+ }
+
+ class δ : Sink<TResult>
+ {
+ private readonly Generate<TState, TResult> _parent;
+
+ public δ(Generate<TState, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private bool _first;
+ private bool _hasResult;
+ private TResult _result;
+
+ public IDisposable Run()
+ {
+ _first = true;
+ _hasResult = false;
+ _result = default(TResult);
+
+ return _parent._scheduler.Schedule(_parent._initialState, InvokeRec);
+ }
+
+ private IDisposable InvokeRec(IScheduler self, TState state)
+ {
+ var time = default(TimeSpan);
+
+ if (_hasResult)
+ base._observer.OnNext(_result);
+ try
+ {
+ if (_first)
+ _first = false;
+ else
+ state = _parent._iterate(state);
+ _hasResult = _parent._condition(state);
+ if (_hasResult)
+ {
+ _result = _parent._resultSelector(state);
+ time = _parent._timeSelectorR(state);
+ }
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ if (!_hasResult)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ return self.Schedule(state, time, InvokeRec);
+ }
+ }
+
+ class _ : Sink<TResult>
+ {
+ private readonly Generate<TState, TResult> _parent;
+
+ public _(Generate<TState, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private TState _state;
+ private bool _first;
+
+ public IDisposable Run()
+ {
+ _state = _parent._initialState;
+ _first = true;
+
+ var longRunning = _parent._scheduler.AsLongRunning();
+ if (longRunning != null)
+ {
+ return longRunning.ScheduleLongRunning(Loop);
+ }
+ else
+ {
+ return _parent._scheduler.Schedule(LoopRec);
+ }
+ }
+
+ private void Loop(ICancelable cancel)
+ {
+ while (!cancel.IsDisposed)
+ {
+ var hasResult = false;
+ var result = default(TResult);
+ try
+ {
+ if (_first)
+ _first = false;
+ else
+ _state = _parent._iterate(_state);
+ hasResult = _parent._condition(_state);
+ if (hasResult)
+ result = _parent._resultSelector(_state);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ if (hasResult)
+ base._observer.OnNext(result);
+ else
+ break;
+ }
+
+ if (!cancel.IsDisposed)
+ base._observer.OnCompleted();
+
+ base.Dispose();
+ }
+
+ private void LoopRec(Action recurse)
+ {
+ var hasResult = false;
+ var result = default(TResult);
+ try
+ {
+ if (_first)
+ _first = false;
+ else
+ _state = _parent._iterate(_state);
+ hasResult = _parent._condition(_state);
+ if (hasResult)
+ result = _parent._resultSelector(_state);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ if (hasResult)
+ {
+ base._observer.OnNext(result);
+ recurse();
+ }
+ else
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GetEnumerator.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GetEnumerator.cs
new file mode 100644
index 0000000..05bf20b
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GetEnumerator.cs
@@ -0,0 +1,102 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF && !NO_CDS
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reactive.Disposables;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class GetEnumerator<TSource> : IEnumerator<TSource>, IObserver<TSource>
+ {
+ private readonly ConcurrentQueue<TSource> _queue;
+ private TSource _current;
+ private Exception _error;
+ private bool _done;
+ private bool _disposed;
+
+ private readonly SemaphoreSlim _gate;
+ private readonly SingleAssignmentDisposable _subscription;
+
+ public GetEnumerator()
+ {
+ _queue = new ConcurrentQueue<TSource>();
+ _gate = new SemaphoreSlim(0);
+ _subscription = new SingleAssignmentDisposable();
+ }
+
+ public IEnumerator<TSource> Run(IObservable<TSource> source)
+ {
+ //
+ // [OK] Use of unsafe Subscribe: non-pretentious exact mirror with the dual GetEnumerator method.
+ //
+ _subscription.Disposable = source.Subscribe/*Unsafe*/(this);
+ return this;
+ }
+
+ public void OnNext(TSource value)
+ {
+ _queue.Enqueue(value);
+ _gate.Release();
+ }
+
+ public void OnError(Exception error)
+ {
+ _error = error;
+ _subscription.Dispose();
+ _gate.Release();
+ }
+
+ public void OnCompleted()
+ {
+ _done = true;
+ _subscription.Dispose();
+ _gate.Release();
+ }
+
+ public bool MoveNext()
+ {
+ _gate.Wait();
+
+ if (_disposed)
+ throw new ObjectDisposedException("");
+
+ if (_queue.TryDequeue(out _current))
+ return true;
+
+ _error.ThrowIfNotNull();
+
+ Debug.Assert(_done);
+
+ _gate.Release(); // In the (rare) case the user calls MoveNext again we shouldn't block!
+ return false;
+ }
+
+ public TSource Current
+ {
+ get { return _current; }
+ }
+
+ object Collections.IEnumerator.Current
+ {
+ get { return _current; }
+ }
+
+ public void Dispose()
+ {
+ _subscription.Dispose();
+
+ _disposed = true;
+ _gate.Release();
+ }
+
+ public void Reset()
+ {
+ throw new NotSupportedException();
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupBy.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupBy.cs
new file mode 100644
index 0000000..c840b0d
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupBy.cs
@@ -0,0 +1,129 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class GroupBy<TSource, TKey, TElement> : Producer<IGroupedObservable<TKey, TElement>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TKey> _keySelector;
+ private readonly Func<TSource, TElement> _elementSelector;
+ private readonly IEqualityComparer<TKey> _comparer;
+
+ public GroupBy(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+ {
+ _source = source;
+ _keySelector = keySelector;
+ _elementSelector = elementSelector;
+ _comparer = comparer;
+ }
+
+ private CompositeDisposable _groupDisposable;
+ private RefCountDisposable _refCountDisposable;
+
+ protected override IDisposable Run(IObserver<IGroupedObservable<TKey, TElement>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ _groupDisposable = new CompositeDisposable();
+ _refCountDisposable = new RefCountDisposable(_groupDisposable);
+
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ _groupDisposable.Add(_source.SubscribeSafe(sink));
+
+ return _refCountDisposable;
+ }
+
+ class _ : Sink<IGroupedObservable<TKey, TElement>>, IObserver<TSource>
+ {
+ private readonly GroupBy<TSource, TKey, TElement> _parent;
+ private readonly Dictionary<TKey, ISubject<TElement>> _map;
+
+ public _(GroupBy<TSource, TKey, TElement> parent, IObserver<IGroupedObservable<TKey, TElement>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _map = new Dictionary<TKey, ISubject<TElement>>(_parent._comparer);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var key = default(TKey);
+ try
+ {
+ key = _parent._keySelector(value);
+ }
+ catch (Exception exception)
+ {
+ Error(exception);
+ return;
+ }
+
+ var fireNewMapEntry = false;
+ var writer = default(ISubject<TElement>);
+ try
+ {
+ if (!_map.TryGetValue(key, out writer))
+ {
+ writer = new Subject<TElement>();
+ _map.Add(key, writer);
+ fireNewMapEntry = true;
+ }
+ }
+ catch (Exception exception)
+ {
+ Error(exception);
+ return;
+ }
+
+ if (fireNewMapEntry)
+ {
+ var group = new GroupedObservable<TKey, TElement>(key, writer, _parent._refCountDisposable);
+ _observer.OnNext(group);
+ }
+
+ var element = default(TElement);
+ try
+ {
+ element = _parent._elementSelector(value);
+ }
+ catch (Exception exception)
+ {
+ Error(exception);
+ return;
+ }
+
+ writer.OnNext(element);
+ }
+
+ public void OnError(Exception error)
+ {
+ Error(error);
+ }
+
+ public void OnCompleted()
+ {
+ foreach (var w in _map.Values)
+ w.OnCompleted();
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+
+ private void Error(Exception exception)
+ {
+ foreach (var w in _map.Values)
+ w.OnError(exception);
+
+ base._observer.OnError(exception);
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupByUntil.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupByUntil.cs
new file mode 100644
index 0000000..dfc843d
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupByUntil.cs
@@ -0,0 +1,289 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class GroupByUntil<TSource, TKey, TElement, TDuration> : Producer<IGroupedObservable<TKey, TElement>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TKey> _keySelector;
+ private readonly Func<TSource, TElement> _elementSelector;
+ private readonly Func<IGroupedObservable<TKey, TElement>, IObservable<TDuration>> _durationSelector;
+ private readonly IEqualityComparer<TKey> _comparer;
+
+ public GroupByUntil(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedObservable<TKey, TElement>, IObservable<TDuration>> durationSelector, IEqualityComparer<TKey> comparer)
+ {
+ _source = source;
+ _keySelector = keySelector;
+ _elementSelector = elementSelector;
+ _durationSelector = durationSelector;
+ _comparer = comparer;
+ }
+
+ private CompositeDisposable _groupDisposable;
+ private RefCountDisposable _refCountDisposable;
+
+ protected override IDisposable Run(IObserver<IGroupedObservable<TKey, TElement>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ _groupDisposable = new CompositeDisposable();
+ _refCountDisposable = new RefCountDisposable(_groupDisposable);
+
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ _groupDisposable.Add(_source.SubscribeSafe(sink));
+
+ return _refCountDisposable;
+ }
+
+ class _ : Sink<IGroupedObservable<TKey, TElement>>, IObserver<TSource>
+ {
+ private readonly GroupByUntil<TSource, TKey, TElement, TDuration> _parent;
+ private readonly Map<TKey, ISubject<TElement>> _map;
+
+ public _(GroupByUntil<TSource, TKey, TElement, TDuration> parent, IObserver<IGroupedObservable<TKey, TElement>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _map = new Map<TKey, ISubject<TElement>>(_parent._comparer);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var key = default(TKey);
+ try
+ {
+ key = _parent._keySelector(value);
+ }
+ catch (Exception exception)
+ {
+ Error(exception);
+ return;
+ }
+
+ var fireNewMapEntry = false;
+ var writer = default(ISubject<TElement>);
+ try
+ {
+ writer = _map.GetOrAdd(key, () => new Subject<TElement>(), out fireNewMapEntry);
+ }
+ catch (Exception exception)
+ {
+ Error(exception);
+ return;
+ }
+
+ if (fireNewMapEntry)
+ {
+ var group = new GroupedObservable<TKey, TElement>(key, writer, _parent._refCountDisposable);
+
+ var duration = default(IObservable<TDuration>);
+
+ var durationGroup = new GroupedObservable<TKey, TElement>(key, writer);
+ try
+ {
+ duration = _parent._durationSelector(durationGroup);
+ }
+ catch (Exception exception)
+ {
+ Error(exception);
+ return;
+ }
+
+ lock (base._observer)
+ base._observer.OnNext(group);
+
+ var md = new SingleAssignmentDisposable();
+ _parent._groupDisposable.Add(md);
+ md.Disposable = duration.SubscribeSafe(new δ(this, key, writer, md));
+ }
+
+ var element = default(TElement);
+ try
+ {
+ element = _parent._elementSelector(value);
+ }
+ catch (Exception exception)
+ {
+ Error(exception);
+ return;
+ }
+
+ writer.OnNext(element);
+ }
+
+ class δ : IObserver<TDuration>
+ {
+ private readonly _ _parent;
+ private readonly TKey _key;
+ private readonly ISubject<TElement> _writer;
+ private readonly IDisposable _self;
+
+ public δ(_ parent, TKey key, ISubject<TElement> writer, IDisposable self)
+ {
+ _parent = parent;
+ _key = key;
+ _writer = writer;
+ _self = self;
+ }
+
+ public void OnNext(TDuration value)
+ {
+ if (_parent._map.Remove(_key))
+ _writer.OnCompleted();
+
+ _parent._parent._groupDisposable.Remove(_self);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.Error(error);
+ _self.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (_parent._map.Remove(_key))
+ _writer.OnCompleted();
+
+ _parent._parent._groupDisposable.Remove(_self);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ Error(error);
+ }
+
+ public void OnCompleted()
+ {
+ foreach (var w in _map.Values)
+ w.OnCompleted();
+
+ lock (base._observer)
+ base._observer.OnCompleted();
+
+ base.Dispose();
+ }
+
+ private void Error(Exception exception)
+ {
+ foreach (var w in _map.Values)
+ w.OnError(exception);
+
+ lock (base._observer)
+ base._observer.OnError(exception);
+
+ base.Dispose();
+ }
+ }
+ }
+
+#if !NO_CDS
+ class Map<TKey, TValue>
+ {
+ private readonly System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue> _map;
+
+ public Map(IEqualityComparer<TKey> comparer)
+ {
+ _map = new System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>(comparer);
+ }
+
+ public TValue GetOrAdd(TKey key, Func<TValue> valueFactory, out bool added)
+ {
+ added = false;
+
+ var value = default(TValue);
+ var newValue = default(TValue);
+ var hasNewValue = false;
+ while (true)
+ {
+ if (_map.TryGetValue(key, out value))
+ break;
+
+ if (!hasNewValue)
+ {
+ newValue = valueFactory();
+ hasNewValue = true;
+ }
+
+ if (_map.TryAdd(key, newValue))
+ {
+ added = true;
+ value = newValue;
+ break;
+ }
+ }
+
+ return value;
+ }
+
+ public IEnumerable<TValue> Values
+ {
+ get
+ {
+ return _map.Values.ToArray();
+ }
+ }
+
+ public bool Remove(TKey key)
+ {
+ var value = default(TValue);
+ return _map.TryRemove(key, out value);
+ }
+ }
+#else
+ class Map<TKey, TValue>
+ {
+ private readonly Dictionary<TKey, TValue> _map;
+
+ public Map(IEqualityComparer<TKey> comparer)
+ {
+ _map = new Dictionary<TKey, TValue>(comparer);
+ }
+
+ public TValue GetOrAdd(TKey key, Func<TValue> valueFactory, out bool added)
+ {
+ lock (_map)
+ {
+ added = false;
+
+ var value = default(TValue);
+ if (!_map.TryGetValue(key, out value))
+ {
+ value = valueFactory();
+ _map.Add(key, value);
+ added = true;
+ }
+
+ return value;
+ }
+ }
+
+ public IEnumerable<TValue> Values
+ {
+ get
+ {
+ lock (_map)
+ {
+ return _map.Values.ToArray();
+ }
+ }
+ }
+
+ public bool Remove(TKey key)
+ {
+ lock (_map)
+ {
+ return _map.Remove(key);
+ }
+ }
+ }
+#endif
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupJoin.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupJoin.cs
new file mode 100644
index 0000000..66e49be
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupJoin.cs
@@ -0,0 +1,302 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<TLeft> _left;
+ private readonly IObservable<TRight> _right;
+ private readonly Func<TLeft, IObservable<TLeftDuration>> _leftDurationSelector;
+ private readonly Func<TRight, IObservable<TRightDuration>> _rightDurationSelector;
+ private readonly Func<TLeft, IObservable<TRight>, TResult> _resultSelector;
+
+ public GroupJoin(IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, IObservable<TRight>, TResult> resultSelector)
+ {
+ _left = left;
+ _right = right;
+ _leftDurationSelector = leftDurationSelector;
+ _rightDurationSelector = rightDurationSelector;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>
+ {
+ private readonly GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult> _parent;
+
+ public _(GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private CompositeDisposable _group;
+ private RefCountDisposable _refCount;
+
+ private int _leftID;
+ private Dictionary<int, IObserver<TRight>> _leftMap;
+
+ private int _rightID;
+ private Dictionary<int, TRight> _rightMap;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _group = new CompositeDisposable();
+ _refCount = new RefCountDisposable(_group);
+
+ var leftSubscription = new SingleAssignmentDisposable();
+ _group.Add(leftSubscription);
+ _leftID = 0;
+ _leftMap = new Dictionary<int, IObserver<TRight>>();
+
+ var rightSubscription = new SingleAssignmentDisposable();
+ _group.Add(rightSubscription);
+ _rightID = 0;
+ _rightMap = new Dictionary<int, TRight>();
+
+ leftSubscription.Disposable = _parent._left.SubscribeSafe(new λ(this, leftSubscription));
+ rightSubscription.Disposable = _parent._right.SubscribeSafe(new ρ(this, rightSubscription));
+
+ return _refCount;
+ }
+
+ class λ : IObserver<TLeft>
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+
+ public λ(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ private void Expire(int id, IObserver<TRight> group, IDisposable resource)
+ {
+ lock (_parent._gate)
+ if (_parent._leftMap.Remove(id))
+ group.OnCompleted();
+
+ _parent._group.Remove(resource);
+ }
+
+ public void OnNext(TLeft value)
+ {
+ var s = new Subject<TRight>();
+ var id = 0;
+ lock (_parent._gate)
+ {
+ id = _parent._leftID++;
+ _parent._leftMap.Add(id, s);
+ }
+
+ var window = new WindowObservable<TRight>(s, _parent._refCount);
+
+ // BREAKING CHANGE v2 > v1.x - Order of evaluation or the _leftDurationSelector and _resultSelector now consistent with Join.
+ var md = new SingleAssignmentDisposable();
+ _parent._group.Add(md);
+
+ var duration = default(IObservable<TLeftDuration>);
+ try
+ {
+ duration = _parent._parent._leftDurationSelector(value);
+ }
+ catch (Exception exception)
+ {
+ OnError(exception);
+ return;
+ }
+
+ // BREAKING CHANGE v2 > v1.x - The duration sequence is subscribed to before the result sequence is evaluated.
+ md.Disposable = duration.SubscribeSafe(new δ(this, id, s, md));
+
+ var result = default(TResult);
+ try
+ {
+ result = _parent._parent._resultSelector(value, window);
+ }
+ catch (Exception exception)
+ {
+ OnError(exception);
+ return;
+ }
+
+ lock (_parent._gate)
+ {
+ _parent._observer.OnNext(result);
+
+ foreach (var rightValue in _parent._rightMap.Values)
+ {
+ s.OnNext(rightValue);
+ }
+ }
+ }
+
+ class δ : IObserver<TLeftDuration>
+ {
+ private readonly λ _parent;
+ private readonly int _id;
+ private readonly IObserver<TRight> _group;
+ private readonly IDisposable _self;
+
+ public δ(λ parent, int id, IObserver<TRight> group, IDisposable self)
+ {
+ _parent = parent;
+ _id = id;
+ _group = group;
+ _self = self;
+ }
+
+ public void OnNext(TLeftDuration value)
+ {
+ _parent.Expire(_id, _group, _self);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.OnError(error);
+ }
+
+ public void OnCompleted()
+ {
+ _parent.Expire(_id, _group, _self);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ foreach (var o in _parent._leftMap.Values)
+ o.OnError(error);
+
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+
+ _self.Dispose();
+ }
+ }
+
+ class ρ : IObserver<TRight>
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+
+ public ρ(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ private void Expire(int id, IDisposable resource)
+ {
+ lock (_parent._gate)
+ _parent._rightMap.Remove(id);
+
+ _parent._group.Remove(resource);
+ }
+
+ public void OnNext(TRight value)
+ {
+ var id = 0;
+ lock (_parent._gate)
+ {
+ id = _parent._rightID++;
+ _parent._rightMap.Add(id, value);
+ }
+
+ var md = new SingleAssignmentDisposable();
+ _parent._group.Add(md);
+
+ var duration = default(IObservable<TRightDuration>);
+ try
+ {
+ duration = _parent._parent._rightDurationSelector(value);
+ }
+ catch (Exception exception)
+ {
+ OnError(exception);
+ return;
+ }
+ md.Disposable = duration.SubscribeSafe(new δ(this, id, md));
+
+ lock (_parent._gate)
+ {
+ foreach (var o in _parent._leftMap.Values)
+ o.OnNext(value);
+ }
+ }
+
+ class δ : IObserver<TRightDuration>
+ {
+ private readonly ρ _parent;
+ private readonly int _id;
+ private readonly IDisposable _self;
+
+ public δ(ρ parent, int id, IDisposable self)
+ {
+ _parent = parent;
+ _id = id;
+ _self = self;
+ }
+
+ public void OnNext(TRightDuration value)
+ {
+ _parent.Expire(_id, _self);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.OnError(error);
+ }
+
+ public void OnCompleted()
+ {
+ _parent.Expire(_id, _self);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ foreach (var o in _parent._leftMap.Values)
+ o.OnError(error);
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _self.Dispose();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/If.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/If.cs
new file mode 100644
index 0000000..8b1804a
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/If.cs
@@ -0,0 +1,81 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class If<TResult> : Producer<TResult>, IEvaluatableObservable<TResult>
+ {
+ private readonly Func<bool> _condition;
+ private readonly IObservable<TResult> _thenSource;
+ private readonly IObservable<TResult> _elseSource;
+
+ public If(Func<bool> condition, IObservable<TResult> thenSource, IObservable<TResult> elseSource)
+ {
+ _condition = condition;
+ _thenSource = thenSource;
+ _elseSource = elseSource;
+ }
+
+ public IObservable<TResult> Eval()
+ {
+ return _condition() ? _thenSource : _elseSource;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>, IObserver<TResult>
+ {
+ private readonly If<TResult> _parent;
+
+ public _(If<TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var result = default(IObservable<TResult>);
+ try
+ {
+ result = _parent.Eval();
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ return result.SubscribeSafe(this);
+ }
+
+ public void OnNext(TResult value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/IgnoreElements.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/IgnoreElements.cs
new file mode 100644
index 0000000..65441bd
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/IgnoreElements.cs
@@ -0,0 +1,54 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class IgnoreElements<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+
+ public IgnoreElements(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ public IObservable<TSource> Ω()
+ {
+ return this;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ public _(IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public void OnNext(TSource value)
+ {
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/IsEmpty.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/IsEmpty.cs
new file mode 100644
index 0000000..674c6f8
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/IsEmpty.cs
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class IsEmpty<TSource> : Producer<bool>
+ {
+ private readonly IObservable<TSource> _source;
+
+ public IsEmpty(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<bool>, IObserver<TSource>
+ {
+ public _(IObserver<bool> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(false);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(true);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Join.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Join.cs
new file mode 100644
index 0000000..13e6ad2
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Join.cs
@@ -0,0 +1,336 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<TLeft> _left;
+ private readonly IObservable<TRight> _right;
+ private readonly Func<TLeft, IObservable<TLeftDuration>> _leftDurationSelector;
+ private readonly Func<TRight, IObservable<TRightDuration>> _rightDurationSelector;
+ private readonly Func<TLeft, TRight, TResult> _resultSelector;
+
+ public Join(IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, TRight, TResult> resultSelector)
+ {
+ _left = left;
+ _right = right;
+ _leftDurationSelector = leftDurationSelector;
+ _rightDurationSelector = rightDurationSelector;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>
+ {
+ private readonly Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult> _parent;
+
+ public _(Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private CompositeDisposable _group;
+
+ private bool _leftDone;
+ private int _leftID;
+ private Dictionary<int, TLeft> _leftMap;
+
+ private bool _rightDone;
+ private int _rightID;
+ private Dictionary<int, TRight> _rightMap;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _group = new CompositeDisposable();
+
+ var leftSubscription = new SingleAssignmentDisposable();
+ _group.Add(leftSubscription);
+ _leftDone = false;
+ _leftID = 0;
+ _leftMap = new Dictionary<int, TLeft>();
+
+ var rightSubscription = new SingleAssignmentDisposable();
+ _group.Add(rightSubscription);
+ _rightDone = false;
+ _rightID = 0;
+ _rightMap = new Dictionary<int, TRight>();
+
+ leftSubscription.Disposable = _parent._left.SubscribeSafe(new λ(this, leftSubscription));
+ rightSubscription.Disposable = _parent._right.SubscribeSafe(new ρ(this, rightSubscription));
+
+ return _group;
+ }
+
+ class λ : IObserver<TLeft>
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+
+ public λ(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ private void Expire(int id, IDisposable resource)
+ {
+ lock (_parent._gate)
+ {
+ if (_parent._leftMap.Remove(id) && _parent._leftMap.Count == 0 && _parent._leftDone)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+
+ _parent._group.Remove(resource);
+ }
+
+ public void OnNext(TLeft value)
+ {
+ var id = 0;
+ lock (_parent._gate)
+ {
+ id = _parent._leftID++;
+ _parent._leftMap.Add(id, value);
+ }
+
+ var md = new SingleAssignmentDisposable();
+ _parent._group.Add(md);
+
+ var duration = default(IObservable<TLeftDuration>);
+ try
+ {
+ duration = _parent._parent._leftDurationSelector(value);
+ }
+ catch (Exception exception)
+ {
+ _parent._observer.OnError(exception);
+ _parent.Dispose();
+ return;
+ }
+
+ md.Disposable = duration.SubscribeSafe(new δ(this, id, md));
+
+ lock (_parent._gate)
+ {
+ foreach (var rightValue in _parent._rightMap.Values)
+ {
+ var result = default(TResult);
+ try
+ {
+ result = _parent._parent._resultSelector(value, rightValue);
+ }
+ catch (Exception exception)
+ {
+ _parent._observer.OnError(exception);
+ _parent.Dispose();
+ return;
+ }
+
+ _parent._observer.OnNext(result);
+ }
+ }
+ }
+
+ class δ : IObserver<TLeftDuration>
+ {
+ private readonly λ _parent;
+ private readonly int _id;
+ private readonly IDisposable _self;
+
+ public δ(λ parent, int id, IDisposable self)
+ {
+ _parent = parent;
+ _id = id;
+ _self = self;
+ }
+
+ public void OnNext(TLeftDuration value)
+ {
+ _parent.Expire(_id, _self);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.OnError(error);
+ }
+
+ public void OnCompleted()
+ {
+ _parent.Expire(_id, _self);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ _parent._leftDone = true;
+ if (_parent._rightDone || _parent._leftMap.Count == 0)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ else
+ {
+ _self.Dispose();
+ }
+ }
+ }
+ }
+
+ class ρ : IObserver<TRight>
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+
+ public ρ(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ private void Expire(int id, IDisposable resource)
+ {
+ lock (_parent._gate)
+ {
+ if (_parent._rightMap.Remove(id) && _parent._rightMap.Count == 0 && _parent._rightDone)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+
+ _parent._group.Remove(resource);
+ }
+
+ public void OnNext(TRight value)
+ {
+ var id = 0;
+ lock (_parent._gate)
+ {
+ id = _parent._rightID++;
+ _parent._rightMap.Add(id, value);
+ }
+
+ var md = new SingleAssignmentDisposable();
+ _parent._group.Add(md);
+
+ var duration = default(IObservable<TRightDuration>);
+ try
+ {
+ duration = _parent._parent._rightDurationSelector(value);
+ }
+ catch (Exception exception)
+ {
+ _parent._observer.OnError(exception);
+ _parent.Dispose();
+ return;
+ }
+
+ md.Disposable = duration.SubscribeSafe(new δ(this, id, md));
+
+ lock (_parent._gate)
+ {
+ foreach (var leftValue in _parent._leftMap.Values)
+ {
+ var result = default(TResult);
+ try
+ {
+ result = _parent._parent._resultSelector(leftValue, value);
+ }
+ catch (Exception exception)
+ {
+ _parent._observer.OnError(exception);
+ _parent.Dispose();
+ return;
+ }
+
+ _parent._observer.OnNext(result);
+ }
+ }
+ }
+
+ class δ : IObserver<TRightDuration>
+ {
+ private readonly ρ _parent;
+ private readonly int _id;
+ private readonly IDisposable _self;
+
+ public δ(ρ parent, int id, IDisposable self)
+ {
+ _parent = parent;
+ _id = id;
+ _self = self;
+ }
+
+ public void OnNext(TRightDuration value)
+ {
+ _parent.Expire(_id, _self);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.OnError(error);
+ }
+
+ public void OnCompleted()
+ {
+ _parent.Expire(_id, _self);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ _parent._rightDone = true;
+ if (_parent._leftDone || _parent._rightMap.Count == 0)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ else
+ {
+ _self.Dispose();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/LastAsync.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/LastAsync.cs
new file mode 100644
index 0000000..1ecd930
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/LastAsync.cs
@@ -0,0 +1,140 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class LastAsync<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+ private readonly bool _throwOnEmpty;
+
+ public LastAsync(IObservable<TSource> source, Func<TSource, bool> predicate, bool throwOnEmpty)
+ {
+ _source = source;
+ _predicate = predicate;
+ _throwOnEmpty = throwOnEmpty;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_predicate != null)
+ {
+ var sink = new π(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly LastAsync<TSource> _parent;
+ private TSource _value;
+ private bool _seenValue;
+
+ public _(LastAsync<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+
+ _value = default(TSource);
+ _seenValue = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ _value = value;
+ _seenValue = true;
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_seenValue && _parent._throwOnEmpty)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_value);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+
+ class π : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly LastAsync<TSource> _parent;
+ private TSource _value;
+ private bool _seenValue;
+
+ public π(LastAsync<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+
+ _value = default(TSource);
+ _seenValue = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var b = false;
+
+ try
+ {
+ b = _parent._predicate(value);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (b)
+ {
+ _value = value;
+ _seenValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_seenValue && _parent._throwOnEmpty)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_MATCHING_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_value);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Latest.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Latest.cs
new file mode 100644
index 0000000..2699797
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Latest.cs
@@ -0,0 +1,145 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Threading;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Latest<TSource> : PushToPullAdapter<TSource, TSource>
+ {
+ public Latest(IObservable<TSource> source)
+ : base(source)
+ {
+ }
+
+ protected override PushToPullSink<TSource, TSource> Run(IDisposable subscription)
+ {
+ return new _(subscription);
+ }
+
+ class _ : PushToPullSink<TSource, TSource>
+ {
+ private readonly object _gate;
+
+#if !NO_CDS
+ private readonly SemaphoreSlim _semaphore;
+#else
+ private readonly Semaphore _semaphore;
+#endif
+
+ public _(IDisposable subscription)
+ : base(subscription)
+ {
+ _gate = new object();
+
+#if !NO_CDS
+ _semaphore = new SemaphoreSlim(0, 1);
+#else
+ _semaphore = new Semaphore(0, 1);
+#endif
+ }
+
+ private bool _notificationAvailable;
+ private NotificationKind _kind;
+ private TSource _value;
+ private Exception _error;
+
+ public override void OnNext(TSource value)
+ {
+ var lackedValue = false;
+ lock (_gate)
+ {
+ lackedValue = !_notificationAvailable;
+ _notificationAvailable = true;
+ _kind = NotificationKind.OnNext;
+ _value = value;
+ }
+
+ if (lackedValue)
+ _semaphore.Release();
+ }
+
+ public override void OnError(Exception error)
+ {
+ base.Dispose();
+
+ var lackedValue = false;
+ lock (_gate)
+ {
+ lackedValue = !_notificationAvailable;
+ _notificationAvailable = true;
+ _kind = NotificationKind.OnError;
+ _error = error;
+ }
+
+ if (lackedValue)
+ _semaphore.Release();
+ }
+
+ public override void OnCompleted()
+ {
+ base.Dispose();
+
+ var lackedValue = false;
+ lock (_gate)
+ {
+ lackedValue = !_notificationAvailable;
+ _notificationAvailable = true;
+ _kind = NotificationKind.OnCompleted;
+ }
+
+ if (lackedValue)
+ _semaphore.Release();
+ }
+
+ public override bool TryMoveNext(out TSource current)
+ {
+ var kind = default(NotificationKind);
+ var value = default(TSource);
+ var error = default(Exception);
+
+#if !NO_CDS
+ _semaphore.Wait();
+#else
+ _semaphore.WaitOne();
+#endif
+
+ lock (_gate)
+ {
+ kind = _kind;
+
+ switch (kind)
+ {
+ case NotificationKind.OnNext:
+ value = _value;
+ break;
+ case NotificationKind.OnError:
+ error = _error;
+ break;
+ }
+
+ _notificationAvailable = false;
+ }
+
+ switch (kind)
+ {
+ case NotificationKind.OnNext:
+ current = _value;
+ return true;
+ case NotificationKind.OnError:
+ error.Throw();
+ break;
+ case NotificationKind.OnCompleted:
+ break;
+ }
+
+ current = default(TSource);
+ return false;
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/LongCount.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/LongCount.cs
new file mode 100644
index 0000000..0108e18
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/LongCount.cs
@@ -0,0 +1,124 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class LongCount<TSource> : Producer<long>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+
+ public LongCount(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ public LongCount(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ _source = source;
+ _predicate = predicate;
+ }
+
+ protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_predicate == null)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new π(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<long>, IObserver<TSource>
+ {
+ private long _count;
+
+ public _(IObserver<long> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _count = 0L;
+ }
+
+ public void OnNext(TSource value)
+ {
+ try
+ {
+ checked
+ {
+ _count++;
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_count);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class π : Sink<long>, IObserver<TSource>
+ {
+ private readonly LongCount<TSource> _parent;
+ private long _count;
+
+ public π(LongCount<TSource> parent, IObserver<long> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _count = 0L;
+ }
+
+ public void OnNext(TSource value)
+ {
+ try
+ {
+ checked
+ {
+ if (_parent._predicate(value))
+ _count++;
+ }
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_count);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Materialize.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Materialize.cs
new file mode 100644
index 0000000..102267d
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Materialize.cs
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Materialize<TSource> : Producer<Notification<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+
+ public Materialize(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ public IObservable<TSource> Dematerialize()
+ {
+ return _source.AsObservable();
+ }
+
+ protected override IDisposable Run(IObserver<Notification<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<Notification<TSource>>, IObserver<TSource>
+ {
+ public _(IObserver<Notification<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(Notification.CreateOnNext<TSource>(value));
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnNext(Notification.CreateOnError<TSource>(error));
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(Notification.CreateOnCompleted<TSource>());
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Max.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Max.cs
new file mode 100644
index 0000000..da339da
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Max.cs
@@ -0,0 +1,792 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Max<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly IComparer<TSource> _comparer;
+
+ public Max(IObservable<TSource> source, IComparer<TSource> comparer)
+ {
+ _source = source;
+ _comparer = comparer;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ // LINQ to Objects makes this distinction in order to make [Max|Max] of an empty collection of reference type objects equal to null.
+ if (default(TSource) == null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new δ(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class δ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Max<TSource> _parent;
+ private bool _hasValue;
+ private TSource _lastValue;
+
+ public δ(Max<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+
+ _hasValue = false;
+ _lastValue = default(TSource);
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_hasValue)
+ {
+ var comparison = 0;
+
+ try
+ {
+ comparison = _parent._comparer.Compare(value, _lastValue);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (comparison > 0)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _hasValue = true;
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Max<TSource> _parent;
+ private TSource _lastValue;
+
+ public _(Max<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+
+ _lastValue = default(TSource);
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (value != null)
+ {
+ if (_lastValue == null)
+ {
+ _lastValue = value;
+ }
+ else
+ {
+ var comparison = 0;
+
+ try
+ {
+ comparison = _parent._comparer.Compare(value, _lastValue);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (comparison > 0)
+ {
+ _lastValue = value;
+ }
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class MaxDouble : Producer<double>
+ {
+ private readonly IObservable<double> _source;
+
+ public MaxDouble(IObservable<double> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double>, IObserver<double>
+ {
+ private bool _hasValue;
+ private double _lastValue;
+
+ public _(IObserver<double> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _hasValue = false;
+ _lastValue = default(double);
+ }
+
+ public void OnNext(double value)
+ {
+ if (_hasValue)
+ {
+ if (value > _lastValue || double.IsNaN(value))
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ _hasValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class MaxSingle : Producer<float>
+ {
+ private readonly IObservable<float> _source;
+
+ public MaxSingle(IObservable<float> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<float> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<float>, IObserver<float>
+ {
+ private bool _hasValue;
+ private float _lastValue;
+
+ public _(IObserver<float> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _hasValue = false;
+ _lastValue = default(float);
+ }
+
+ public void OnNext(float value)
+ {
+ if (_hasValue)
+ {
+ if (value > _lastValue || float.IsNaN(value))
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ _hasValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class MaxDecimal : Producer<decimal>
+ {
+ private readonly IObservable<decimal> _source;
+
+ public MaxDecimal(IObservable<decimal> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<decimal> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<decimal>, IObserver<decimal>
+ {
+ private bool _hasValue;
+ private decimal _lastValue;
+
+ public _(IObserver<decimal> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _hasValue = false;
+ _lastValue = default(decimal);
+ }
+
+ public void OnNext(decimal value)
+ {
+ if (_hasValue)
+ {
+ if (value > _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ _hasValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class MaxInt32 : Producer<int>
+ {
+ private readonly IObservable<int> _source;
+
+ public MaxInt32(IObservable<int> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<int>, IObserver<int>
+ {
+ private bool _hasValue;
+ private int _lastValue;
+
+ public _(IObserver<int> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _hasValue = false;
+ _lastValue = default(int);
+ }
+
+ public void OnNext(int value)
+ {
+ if (_hasValue)
+ {
+ if (value > _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ _hasValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class MaxInt64 : Producer<long>
+ {
+ private readonly IObservable<long> _source;
+
+ public MaxInt64(IObservable<long> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<long>, IObserver<long>
+ {
+ private bool _hasValue;
+ private long _lastValue;
+
+ public _(IObserver<long> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _hasValue = false;
+ _lastValue = default(long);
+ }
+
+ public void OnNext(long value)
+ {
+ if (_hasValue)
+ {
+ if (value > _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ _hasValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class MaxDoubleNullable : Producer<double?>
+ {
+ private readonly IObservable<double?> _source;
+
+ public MaxDoubleNullable(IObservable<double?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double?>, IObserver<double?>
+ {
+ private double? _lastValue;
+
+ public _(IObserver<double?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _lastValue = default(double?);
+ }
+
+ public void OnNext(double? value)
+ {
+ if (!value.HasValue)
+ return;
+
+ if (_lastValue.HasValue)
+ {
+ if (value > _lastValue || double.IsNaN((double)value))
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class MaxSingleNullable : Producer<float?>
+ {
+ private readonly IObservable<float?> _source;
+
+ public MaxSingleNullable(IObservable<float?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<float?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<float?>, IObserver<float?>
+ {
+ private float? _lastValue;
+
+ public _(IObserver<float?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _lastValue = default(float?);
+ }
+
+ public void OnNext(float? value)
+ {
+ if (!value.HasValue)
+ return;
+
+ if (_lastValue.HasValue)
+ {
+ if (value > _lastValue || float.IsNaN((float)value))
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class MaxDecimalNullable : Producer<decimal?>
+ {
+ private readonly IObservable<decimal?> _source;
+
+ public MaxDecimalNullable(IObservable<decimal?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<decimal?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<decimal?>, IObserver<decimal?>
+ {
+ private decimal? _lastValue;
+
+ public _(IObserver<decimal?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _lastValue = default(decimal?);
+ }
+
+ public void OnNext(decimal? value)
+ {
+ if (!value.HasValue)
+ return;
+
+ if (_lastValue.HasValue)
+ {
+ if (value > _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class MaxInt32Nullable : Producer<int?>
+ {
+ private readonly IObservable<int?> _source;
+
+ public MaxInt32Nullable(IObservable<int?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<int?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<int?>, IObserver<int?>
+ {
+ private int? _lastValue;
+
+ public _(IObserver<int?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _lastValue = default(int?);
+ }
+
+ public void OnNext(int? value)
+ {
+ if (!value.HasValue)
+ return;
+
+ if (_lastValue.HasValue)
+ {
+ if (value > _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class MaxInt64Nullable : Producer<long?>
+ {
+ private readonly IObservable<long?> _source;
+
+ public MaxInt64Nullable(IObservable<long?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<long?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<long?>, IObserver<long?>
+ {
+ private long? _lastValue;
+
+ public _(IObserver<long?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _lastValue = default(long?);
+ }
+
+ public void OnNext(long? value)
+ {
+ if (!value.HasValue)
+ return;
+
+ if (_lastValue.HasValue)
+ {
+ if (value > _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MaxBy.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MaxBy.cs
new file mode 100644
index 0000000..52a9a42
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MaxBy.cs
@@ -0,0 +1,108 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class MaxBy<TSource, TKey> : Producer<IList<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TKey> _keySelector;
+ private readonly IComparer<TKey> _comparer;
+
+ public MaxBy(IObservable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
+ {
+ _source = source;
+ _keySelector = keySelector;
+ _comparer = comparer;
+ }
+
+ protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private readonly MaxBy<TSource, TKey> _parent;
+ private bool _hasValue;
+ private TKey _lastKey;
+ private List<TSource> _list;
+
+ public _(MaxBy<TSource, TKey> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+
+ _hasValue = false;
+ _lastKey = default(TKey);
+ _list = new List<TSource>();
+ }
+
+ public void OnNext(TSource value)
+ {
+ var key = default(TKey);
+ try
+ {
+ key = _parent._keySelector(value);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ var comparison = 0;
+
+ if (!_hasValue)
+ {
+ _hasValue = true;
+ _lastKey = key;
+ }
+ else
+ {
+ try
+ {
+ comparison = _parent._comparer.Compare(key, _lastKey);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+ }
+
+ if (comparison > 0)
+ {
+ _lastKey = key;
+ _list.Clear();
+ }
+
+ if (comparison >= 0)
+ {
+ _list.Add(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_list);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Merge.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Merge.cs
new file mode 100644
index 0000000..b051a4b
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Merge.cs
@@ -0,0 +1,288 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Merge<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<IObservable<TSource>> _sources;
+ private readonly int _maxConcurrent;
+
+ public Merge(IObservable<IObservable<TSource>> sources)
+ {
+ _sources = sources;
+ }
+
+ public Merge(IObservable<IObservable<TSource>> sources, int maxConcurrent)
+ {
+ _sources = sources;
+ _maxConcurrent = maxConcurrent;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_maxConcurrent > 0)
+ {
+ var sink = new μ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<IObservable<TSource>>
+ {
+ private readonly Merge<TSource> _parent;
+
+ public _(Merge<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private bool _isStopped;
+ private CompositeDisposable _group;
+ private SingleAssignmentDisposable _sourceSubscription;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _isStopped = false;
+ _group = new CompositeDisposable();
+
+ _sourceSubscription = new SingleAssignmentDisposable();
+ _group.Add(_sourceSubscription);
+ _sourceSubscription.Disposable = _parent._sources.SubscribeSafe(this);
+
+ return _group;
+ }
+
+ public void OnNext(IObservable<TSource> value)
+ {
+ var innerSubscription = new SingleAssignmentDisposable();
+ _group.Add(innerSubscription);
+ innerSubscription.Disposable = value.SubscribeSafe(new ι(this, innerSubscription));
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _isStopped = true;
+ if (_group.Count == 1)
+ {
+ //
+ // Notice there can be a race between OnCompleted of the source and any
+ // of the inner sequences, where both see _group.Count == 1, and one is
+ // waiting for the lock. There won't be a double OnCompleted observation
+ // though, because the call to Dispose silences the observer by swapping
+ // in a NopObserver<T>.
+ //
+ lock (_gate)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ else
+ {
+ _sourceSubscription.Dispose();
+ }
+ }
+
+ class ι : IObserver<TSource>
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+
+ public ι(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_parent._gate)
+ _parent._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _parent._group.Remove(_self);
+ if (_parent._isStopped && _parent._group.Count == 1)
+ {
+ //
+ // Notice there can be a race between OnCompleted of the source and any
+ // of the inner sequences, where both see _group.Count == 1, and one is
+ // waiting for the lock. There won't be a double OnCompleted observation
+ // though, because the call to Dispose silences the observer by swapping
+ // in a NopObserver<T>.
+ //
+ lock (_parent._gate)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+ }
+ }
+
+ class μ : Sink<TSource>, IObserver<IObservable<TSource>>
+ {
+ private readonly Merge<TSource> _parent;
+
+ public μ(Merge<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private Queue<IObservable<TSource>> _q;
+ private bool _isStopped;
+ private SingleAssignmentDisposable _sourceSubscription;
+ private CompositeDisposable _group;
+ private int _activeCount = 0;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _q = new Queue<IObservable<TSource>>();
+ _isStopped = false;
+ _activeCount = 0;
+
+ _group = new CompositeDisposable();
+ _sourceSubscription = new SingleAssignmentDisposable();
+ _sourceSubscription.Disposable = _parent._sources.SubscribeSafe(this);
+ _group.Add(_sourceSubscription);
+
+ return _group;
+ }
+
+ public void OnNext(IObservable<TSource> value)
+ {
+ lock (_gate)
+ {
+ if (_activeCount < _parent._maxConcurrent)
+ {
+ _activeCount++;
+ Subscribe(value);
+ }
+ else
+ _q.Enqueue(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ _isStopped = true;
+ if (_activeCount == 0)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ else
+ {
+ _sourceSubscription.Dispose();
+ }
+ }
+ }
+
+ private void Subscribe(IObservable<TSource> innerSource)
+ {
+ var subscription = new SingleAssignmentDisposable();
+ _group.Add(subscription);
+ subscription.Disposable = innerSource.SubscribeSafe(new ι(this, subscription));
+ }
+
+ class ι : IObserver<TSource>
+ {
+ private readonly μ _parent;
+ private readonly IDisposable _self;
+
+ public ι(μ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_parent._gate)
+ _parent._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _parent._group.Remove(_self);
+ lock (_parent._gate)
+ {
+ if (_parent._q.Count > 0)
+ {
+ var s = _parent._q.Dequeue();
+ _parent.Subscribe(s);
+ }
+ else
+ {
+ _parent._activeCount--;
+ if (_parent._isStopped && _parent._activeCount == 0)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Min.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Min.cs
new file mode 100644
index 0000000..f7b6197
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Min.cs
@@ -0,0 +1,792 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Min<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly IComparer<TSource> _comparer;
+
+ public Min(IObservable<TSource> source, IComparer<TSource> comparer)
+ {
+ _source = source;
+ _comparer = comparer;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ // LINQ to Objects makes this distinction in order to make [Min|Max] of an empty collection of reference type objects equal to null.
+ if (default(TSource) == null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new δ(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class δ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Min<TSource> _parent;
+ private bool _hasValue;
+ private TSource _lastValue;
+
+ public δ(Min<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+
+ _hasValue = false;
+ _lastValue = default(TSource);
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_hasValue)
+ {
+ var comparison = 0;
+
+ try
+ {
+ comparison = _parent._comparer.Compare(value, _lastValue);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (comparison < 0)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _hasValue = true;
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Min<TSource> _parent;
+ private TSource _lastValue;
+
+ public _(Min<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+
+ _lastValue = default(TSource);
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (value != null)
+ {
+ if (_lastValue == null)
+ {
+ _lastValue = value;
+ }
+ else
+ {
+ var comparison = 0;
+
+ try
+ {
+ comparison = _parent._comparer.Compare(value, _lastValue);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (comparison < 0)
+ {
+ _lastValue = value;
+ }
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class MinDouble : Producer<double>
+ {
+ private readonly IObservable<double> _source;
+
+ public MinDouble(IObservable<double> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double>, IObserver<double>
+ {
+ private bool _hasValue;
+ private double _lastValue;
+
+ public _(IObserver<double> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _hasValue = false;
+ _lastValue = default(double);
+ }
+
+ public void OnNext(double value)
+ {
+ if (_hasValue)
+ {
+ if (value < _lastValue || double.IsNaN(value))
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ _hasValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class MinSingle : Producer<float>
+ {
+ private readonly IObservable<float> _source;
+
+ public MinSingle(IObservable<float> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<float> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<float>, IObserver<float>
+ {
+ private bool _hasValue;
+ private float _lastValue;
+
+ public _(IObserver<float> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _hasValue = false;
+ _lastValue = default(float);
+ }
+
+ public void OnNext(float value)
+ {
+ if (_hasValue)
+ {
+ if (value < _lastValue || float.IsNaN(value))
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ _hasValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class MinDecimal : Producer<decimal>
+ {
+ private readonly IObservable<decimal> _source;
+
+ public MinDecimal(IObservable<decimal> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<decimal> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<decimal>, IObserver<decimal>
+ {
+ private bool _hasValue;
+ private decimal _lastValue;
+
+ public _(IObserver<decimal> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _hasValue = false;
+ _lastValue = default(decimal);
+ }
+
+ public void OnNext(decimal value)
+ {
+ if (_hasValue)
+ {
+ if (value < _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ _hasValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class MinInt32 : Producer<int>
+ {
+ private readonly IObservable<int> _source;
+
+ public MinInt32(IObservable<int> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<int>, IObserver<int>
+ {
+ private bool _hasValue;
+ private int _lastValue;
+
+ public _(IObserver<int> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _hasValue = false;
+ _lastValue = default(int);
+ }
+
+ public void OnNext(int value)
+ {
+ if (_hasValue)
+ {
+ if (value < _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ _hasValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class MinInt64 : Producer<long>
+ {
+ private readonly IObservable<long> _source;
+
+ public MinInt64(IObservable<long> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<long>, IObserver<long>
+ {
+ private bool _hasValue;
+ private long _lastValue;
+
+ public _(IObserver<long> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _hasValue = false;
+ _lastValue = default(long);
+ }
+
+ public void OnNext(long value)
+ {
+ if (_hasValue)
+ {
+ if (value < _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ _hasValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_hasValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+
+ class MinDoubleNullable : Producer<double?>
+ {
+ private readonly IObservable<double?> _source;
+
+ public MinDoubleNullable(IObservable<double?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double?>, IObserver<double?>
+ {
+ private double? _lastValue;
+
+ public _(IObserver<double?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _lastValue = default(double?);
+ }
+
+ public void OnNext(double? value)
+ {
+ if (!value.HasValue)
+ return;
+
+ if (_lastValue.HasValue)
+ {
+ if (value < _lastValue || double.IsNaN((double)value))
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class MinSingleNullable : Producer<float?>
+ {
+ private readonly IObservable<float?> _source;
+
+ public MinSingleNullable(IObservable<float?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<float?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<float?>, IObserver<float?>
+ {
+ private float? _lastValue;
+
+ public _(IObserver<float?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _lastValue = default(float?);
+ }
+
+ public void OnNext(float? value)
+ {
+ if (!value.HasValue)
+ return;
+
+ if (_lastValue.HasValue)
+ {
+ if (value < _lastValue || float.IsNaN((float)value))
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class MinDecimalNullable : Producer<decimal?>
+ {
+ private readonly IObservable<decimal?> _source;
+
+ public MinDecimalNullable(IObservable<decimal?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<decimal?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<decimal?>, IObserver<decimal?>
+ {
+ private decimal? _lastValue;
+
+ public _(IObserver<decimal?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _lastValue = default(decimal?);
+ }
+
+ public void OnNext(decimal? value)
+ {
+ if (!value.HasValue)
+ return;
+
+ if (_lastValue.HasValue)
+ {
+ if (value < _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class MinInt32Nullable : Producer<int?>
+ {
+ private readonly IObservable<int?> _source;
+
+ public MinInt32Nullable(IObservable<int?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<int?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<int?>, IObserver<int?>
+ {
+ private int? _lastValue;
+
+ public _(IObserver<int?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _lastValue = default(int?);
+ }
+
+ public void OnNext(int? value)
+ {
+ if (!value.HasValue)
+ return;
+
+ if (_lastValue.HasValue)
+ {
+ if (value < _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class MinInt64Nullable : Producer<long?>
+ {
+ private readonly IObservable<long?> _source;
+
+ public MinInt64Nullable(IObservable<long?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<long?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<long?>, IObserver<long?>
+ {
+ private long? _lastValue;
+
+ public _(IObserver<long?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _lastValue = default(long?);
+ }
+
+ public void OnNext(long? value)
+ {
+ if (!value.HasValue)
+ return;
+
+ if (_lastValue.HasValue)
+ {
+ if (value < _lastValue)
+ {
+ _lastValue = value;
+ }
+ }
+ else
+ {
+ _lastValue = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lastValue);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MinBy.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MinBy.cs
new file mode 100644
index 0000000..a32bf92
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MinBy.cs
@@ -0,0 +1,108 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class MinBy<TSource, TKey> : Producer<IList<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TKey> _keySelector;
+ private readonly IComparer<TKey> _comparer;
+
+ public MinBy(IObservable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
+ {
+ _source = source;
+ _keySelector = keySelector;
+ _comparer = comparer;
+ }
+
+ protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private readonly MinBy<TSource, TKey> _parent;
+ private bool _hasValue;
+ private TKey _lastKey;
+ private List<TSource> _list;
+
+ public _(MinBy<TSource, TKey> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+
+ _hasValue = false;
+ _lastKey = default(TKey);
+ _list = new List<TSource>();
+ }
+
+ public void OnNext(TSource value)
+ {
+ var key = default(TKey);
+ try
+ {
+ key = _parent._keySelector(value);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ var comparison = 0;
+
+ if (!_hasValue)
+ {
+ _hasValue = true;
+ _lastKey = key;
+ }
+ else
+ {
+ try
+ {
+ comparison = _parent._comparer.Compare(key, _lastKey);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+ }
+
+ if (comparison < 0)
+ {
+ _lastKey = key;
+ _list.Clear();
+ }
+
+ if (comparison <= 0)
+ {
+ _list.Add(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_list);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MostRecent.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MostRecent.cs
new file mode 100644
index 0000000..937d811
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MostRecent.cs
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class MostRecent<TSource> : PushToPullAdapter<TSource, TSource>
+ {
+ private readonly TSource _initialValue;
+
+ public MostRecent(IObservable<TSource> source, TSource initialValue)
+ : base(source)
+ {
+ _initialValue = initialValue;
+ }
+
+ protected override PushToPullSink<TSource, TSource> Run(IDisposable subscription)
+ {
+ return new _(_initialValue, subscription);
+ }
+
+ class _ : PushToPullSink<TSource, TSource>
+ {
+ public _(TSource initialValue, IDisposable subscription)
+ : base(subscription)
+ {
+ _kind = NotificationKind.OnNext;
+ _value = initialValue;
+ }
+
+ private volatile NotificationKind _kind;
+ private TSource _value;
+ private Exception _error;
+
+ public override void OnNext(TSource value)
+ {
+ _value = value;
+ _kind = NotificationKind.OnNext; // Write last!
+ }
+
+ public override void OnError(Exception error)
+ {
+ base.Dispose();
+
+ _error = error;
+ _kind = NotificationKind.OnError; // Write last!
+ }
+
+ public override void OnCompleted()
+ {
+ base.Dispose();
+
+ _kind = NotificationKind.OnCompleted; // Write last!
+ }
+
+ public override bool TryMoveNext(out TSource current)
+ {
+ //
+ // Notice the _kind field is marked volatile and read before the other fields.
+ //
+ // In case of a concurrent change, we may read a stale OnNext value, which is
+ // fine because this push-to-pull adapter is about sampling.
+ //
+ switch (_kind)
+ {
+ case NotificationKind.OnNext:
+ current = _value;
+ return true;
+ case NotificationKind.OnError:
+ _error.Throw();
+ break;
+ case NotificationKind.OnCompleted:
+ break;
+ }
+
+ current = default(TSource);
+ return false;
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Multicast.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Multicast.cs
new file mode 100644
index 0000000..4a77300
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Multicast.cs
@@ -0,0 +1,82 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Multicast<TSource, TIntermediate, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<ISubject<TSource, TIntermediate>> _subjectSelector;
+ private readonly Func<IObservable<TIntermediate>, IObservable<TResult>> _selector;
+
+ public Multicast(IObservable<TSource> source, Func<ISubject<TSource, TIntermediate>> subjectSelector, Func<IObservable<TIntermediate>, IObservable<TResult>> selector)
+ {
+ _source = source;
+ _subjectSelector = subjectSelector;
+ _selector = selector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>, IObserver<TResult>
+ {
+ private readonly Multicast<TSource, TIntermediate, TResult> _parent;
+
+ public _(Multicast<TSource, TIntermediate, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var observable = default(IObservable<TResult>);
+ var connectable = default(IConnectableObservable<TIntermediate>);
+ try
+ {
+ var subject = _parent._subjectSelector();
+ connectable = new ConnectableObservable<TSource, TIntermediate>(_parent._source, subject);
+ observable = _parent._selector(connectable);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ var subscription = observable.SubscribeSafe(this);
+ var connection = connectable.Connect();
+
+ return new CompositeDisposable(subscription, connection);
+ }
+
+ public void OnNext(TResult value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Never.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Never.cs
new file mode 100644
index 0000000..a9adc52
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Never.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Never<TResult> : IObservable<TResult>
+ {
+ public IDisposable Subscribe(IObserver<TResult> observer)
+ {
+ if (observer == null)
+ throw new ArgumentNullException("observer");
+
+ return Disposable.Empty;
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Next.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Next.cs
new file mode 100644
index 0000000..2d4ec45
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Next.cs
@@ -0,0 +1,156 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Threading;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Next<TSource> : PushToPullAdapter<TSource, TSource>
+ {
+ public Next(IObservable<TSource> source)
+ : base(source)
+ {
+ }
+
+ protected override PushToPullSink<TSource, TSource> Run(IDisposable subscription)
+ {
+ return new _(subscription);
+ }
+
+ class _ : PushToPullSink<TSource, TSource>
+ {
+ private readonly object _gate;
+
+#if !NO_CDS
+ private readonly SemaphoreSlim _semaphore;
+#else
+ private readonly Semaphore _semaphore;
+#endif
+
+ public _(IDisposable subscription)
+ : base(subscription)
+ {
+ _gate = new object();
+
+#if !NO_CDS
+ _semaphore = new SemaphoreSlim(0, 1);
+#else
+ _semaphore = new Semaphore(0, 1);
+#endif
+ }
+
+ private bool _waiting;
+ private NotificationKind _kind;
+ private TSource _value;
+ private Exception _error;
+
+ public override void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ if (_waiting)
+ {
+ _value = value;
+ _kind = NotificationKind.OnNext;
+ _semaphore.Release();
+ }
+
+ _waiting = false;
+ }
+ }
+
+ public override void OnError(Exception error)
+ {
+ base.Dispose();
+
+ lock (_gate)
+ {
+ //
+ // BREAKING CHANGE v2 > v1.x - Next doesn't block indefinitely when it reaches the end.
+ //
+ _error = error;
+ _kind = NotificationKind.OnError;
+
+ if (_waiting)
+ _semaphore.Release();
+
+ _waiting = false;
+ }
+ }
+
+ public override void OnCompleted()
+ {
+ base.Dispose();
+
+ lock (_gate)
+ {
+ //
+ // BREAKING CHANGE v2 > v1.x - Next doesn't block indefinitely when it reaches the end.
+ //
+ _kind = NotificationKind.OnCompleted;
+
+ if (_waiting)
+ _semaphore.Release();
+
+ _waiting = false;
+ }
+ }
+
+ public override bool TryMoveNext(out TSource current)
+ {
+ var done = false;
+
+ lock (_gate)
+ {
+ _waiting = true;
+
+ //
+ // BREAKING CHANGE v2 > v1.x - Next doesn't block indefinitely when it reaches the end.
+ //
+ done = _kind != NotificationKind.OnNext;
+ }
+
+ if (!done)
+ {
+#if !NO_CDS
+ _semaphore.Wait();
+#else
+ _semaphore.WaitOne();
+#endif
+ }
+
+ //
+ // When we reach this point, we released the lock and got the next notification
+ // from the observer. We assume no concurrent calls to the TryMoveNext method
+ // are made (per general guidance on usage of IEnumerable<T>). If the observer
+ // enters the lock again, it should have quit it first, causing _waiting to be
+ // set to false, hence future accesses of the lock won't set the _kind, _value,
+ // and _error fields, until TryMoveNext is entered again and _waiting is reset
+ // to true. In conclusion, the fields are stable for read below.
+ //
+ // Notice we rely on memory barrier acquire/release behavior due to the use of
+ // the semaphore, not the lock (we're still under the lock when we release the
+ // semaphore in the On* methods!).
+ //
+ switch (_kind)
+ {
+ case NotificationKind.OnNext:
+ current = _value;
+ return true;
+ case NotificationKind.OnError:
+ _error.Throw();
+ break;
+ case NotificationKind.OnCompleted:
+ break;
+ }
+
+ current = default(TSource);
+ return false;
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ObserveOn.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ObserveOn.cs
new file mode 100644
index 0000000..4fe94d3
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ObserveOn.cs
@@ -0,0 +1,87 @@
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class ObserveOn<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly IScheduler _scheduler;
+
+ public ObserveOn(IObservable<TSource> source, IScheduler scheduler)
+ {
+ _source = source;
+ _scheduler = scheduler;
+ }
+
+#if !NO_SYNCCTX
+ private readonly SynchronizationContext _context;
+
+ public ObserveOn(IObservable<TSource> source, SynchronizationContext context)
+ {
+ _source = source;
+ _context = context;
+ }
+#endif
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+#if !NO_SYNCCTX
+ if (_context != null)
+ {
+ var sink = new ς(this, observer, cancel);
+ setSink(sink);
+ return _source.Subscribe(sink);
+ }
+ else
+#endif
+ {
+ var sink = new ObserveOnObserver<TSource>(_scheduler, observer, cancel);
+ setSink(sink);
+ return _source.Subscribe(sink);
+ }
+ }
+
+#if !NO_SYNCCTX
+ class ς : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly ObserveOn<TSource> _parent;
+
+ public ς(ObserveOn<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ _parent._context.PostWithStartComplete(() =>
+ {
+ base._observer.OnNext(value);
+ });
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent._context.PostWithStartComplete(() =>
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ });
+ }
+
+ public void OnCompleted()
+ {
+ _parent._context.PostWithStartComplete(() =>
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ });
+ }
+ }
+#endif
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/OfType.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/OfType.cs
new file mode 100644
index 0000000..07e4515
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/OfType.cs
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class OfType<TSource, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<TSource> _source;
+
+ public OfType(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TResult>, IObserver<TSource>
+ {
+ public _(IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (value is TResult)
+ {
+ base._observer.OnNext((TResult)(object)value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/OnErrorResumeNext.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/OnErrorResumeNext.cs
new file mode 100644
index 0000000..26dfd34
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/OnErrorResumeNext.cs
@@ -0,0 +1,60 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class OnErrorResumeNext<TSource> : Producer<TSource>
+ {
+ private readonly IEnumerable<IObservable<TSource>> _sources;
+
+ public OnErrorResumeNext(IEnumerable<IObservable<TSource>> sources)
+ {
+ _sources = sources;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return sink.Run(_sources);
+ }
+
+ class _ : TailRecursiveSink<TSource>
+ {
+ public _(IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ protected override IEnumerable<IObservable<TSource>> Extract(IObservable<TSource> source)
+ {
+ var oern = source as OnErrorResumeNext<TSource>;
+ if (oern != null)
+ return oern._sources;
+
+ return null;
+ }
+
+ public override void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public override void OnError(Exception error)
+ {
+ _recurse();
+ }
+
+ public override void OnCompleted()
+ {
+ _recurse();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/PushToPullAdapter.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/PushToPullAdapter.cs
new file mode 100644
index 0000000..916d12b
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/PushToPullAdapter.cs
@@ -0,0 +1,93 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ abstract class PushToPullAdapter<TSource, TResult> : IEnumerable<TResult>
+ {
+ private readonly IObservable<TSource> _source;
+
+ public PushToPullAdapter(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public IEnumerator<TResult> GetEnumerator()
+ {
+ var d = new SingleAssignmentDisposable();
+ var res = Run(d);
+ d.Disposable = _source.SubscribeSafe(res);
+ return res;
+ }
+
+ protected abstract PushToPullSink<TSource, TResult> Run(IDisposable subscription);
+ }
+
+ abstract class PushToPullSink<TSource, TResult> : IObserver<TSource>, IEnumerator<TResult>, IDisposable
+ {
+ private readonly IDisposable _subscription;
+
+ public PushToPullSink(IDisposable subscription)
+ {
+ _subscription = subscription;
+ }
+
+ public abstract void OnNext(TSource value);
+ public abstract void OnError(Exception error);
+ public abstract void OnCompleted();
+
+ public abstract bool TryMoveNext(out TResult current);
+
+ private bool _done;
+
+ public bool MoveNext()
+ {
+ if (!_done)
+ {
+ var current = default(TResult);
+ if (TryMoveNext(out current))
+ {
+ Current = current;
+ return true;
+ }
+ else
+ {
+ _done = true;
+ _subscription.Dispose();
+ }
+ }
+
+ return false;
+ }
+
+ public TResult Current
+ {
+ get;
+ private set;
+ }
+
+ object IEnumerator.Current
+ {
+ get { return Current; }
+ }
+
+ public void Reset()
+ {
+ throw new NotSupportedException();
+ }
+
+ public void Dispose()
+ {
+ _subscription.Dispose();
+ }
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Range.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Range.cs
new file mode 100644
index 0000000..c58d94c
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Range.cs
@@ -0,0 +1,83 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Range : Producer<int>
+ {
+ private readonly int _start;
+ private readonly int _count;
+ private readonly IScheduler _scheduler;
+
+ public Range(int start, int count, IScheduler scheduler)
+ {
+ _start = start;
+ _count = count;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<int>
+ {
+ private readonly Range _parent;
+
+ public _(Range parent, IObserver<int> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var longRunning = _parent._scheduler.AsLongRunning();
+ if (longRunning != null)
+ {
+ return longRunning.ScheduleLongRunning(0, Loop);
+ }
+ else
+ {
+ return _parent._scheduler.Schedule(0, LoopRec);
+ }
+ }
+
+ private void Loop(int i, ICancelable cancel)
+ {
+ while (!cancel.IsDisposed && i < _parent._count)
+ {
+ base._observer.OnNext(_parent._start + i);
+ i++;
+ }
+
+ if (!cancel.IsDisposed)
+ base._observer.OnCompleted();
+
+ base.Dispose();
+ }
+
+ private void LoopRec(int i, Action<int> recurse)
+ {
+ if (i < _parent._count)
+ {
+ base._observer.OnNext(_parent._start + i);
+ recurse(i + 1);
+ }
+ else
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/RefCount.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/RefCount.cs
new file mode 100644
index 0000000..1762807
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/RefCount.cs
@@ -0,0 +1,88 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class RefCount<TSource> : Producer<TSource>
+ {
+ private readonly IConnectableObservable<TSource> _source;
+
+ private readonly object _gate;
+ private int _count;
+ private IDisposable _connectableSubscription;
+
+ public RefCount(IConnectableObservable<TSource> source)
+ {
+ _source = source;
+ _gate = new object();
+ _count = 0;
+ _connectableSubscription = default(IDisposable);
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly RefCount<TSource> _parent;
+
+ public _(RefCount<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var subscription = _parent._source.SubscribeSafe(this);
+
+ lock (_parent._gate)
+ {
+ if (++_parent._count == 1)
+ {
+ _parent._connectableSubscription = _parent._source.Connect();
+ }
+ }
+
+ return Disposable.Create(() =>
+ {
+ subscription.Dispose();
+
+ lock (_parent._gate)
+ {
+ if (--_parent._count == 0)
+ {
+ _parent._connectableSubscription.Dispose();
+ }
+ }
+ });
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Repeat.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Repeat.cs
new file mode 100644
index 0000000..fab0607
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Repeat.cs
@@ -0,0 +1,127 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Repeat<TResult> : Producer<TResult>
+ {
+ private readonly TResult _value;
+ private readonly int? _repeatCount;
+ private readonly IScheduler _scheduler;
+
+ public Repeat(TResult value, int? repeatCount, IScheduler scheduler)
+ {
+ _value = value;
+ _repeatCount = repeatCount;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>
+ {
+ private readonly Repeat<TResult> _parent;
+
+ public _(Repeat<TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var longRunning = _parent._scheduler.AsLongRunning();
+ if (longRunning != null)
+ {
+ return Run(longRunning);
+ }
+ else
+ {
+ return Run(_parent._scheduler);
+ }
+ }
+
+ private IDisposable Run(IScheduler scheduler)
+ {
+ if (_parent._repeatCount == null)
+ {
+ return scheduler.Schedule(LoopRecInf);
+ }
+ else
+ {
+ return scheduler.Schedule(_parent._repeatCount.Value, LoopRec);
+ }
+ }
+
+ private void LoopRecInf(Action recurse)
+ {
+ base._observer.OnNext(_parent._value);
+ recurse();
+ }
+
+ private void LoopRec(int n, Action<int> recurse)
+ {
+ if (n > 0)
+ {
+ base._observer.OnNext(_parent._value);
+ n--;
+ }
+
+ if (n == 0)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ return;
+ }
+
+ recurse(n);
+ }
+
+ private IDisposable Run(ISchedulerLongRunning scheduler)
+ {
+ if (_parent._repeatCount == null)
+ {
+ return scheduler.ScheduleLongRunning(LoopInf);
+ }
+ else
+ {
+ return scheduler.ScheduleLongRunning(_parent._repeatCount.Value, Loop);
+ }
+ }
+
+ private void LoopInf(ICancelable cancel)
+ {
+ var value = _parent._value;
+ while (!cancel.IsDisposed)
+ base._observer.OnNext(value);
+
+ base.Dispose();
+ }
+
+ private void Loop(int n, ICancelable cancel)
+ {
+ var value = _parent._value;
+ while (n > 0 && !cancel.IsDisposed)
+ {
+ base._observer.OnNext(value);
+ n--;
+ }
+
+ if (!cancel.IsDisposed)
+ base._observer.OnCompleted();
+
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Return.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Return.cs
new file mode 100644
index 0000000..cd9ad02
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Return.cs
@@ -0,0 +1,51 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Return<TResult> : Producer<TResult>
+ {
+ private readonly TResult _value;
+ private readonly IScheduler _scheduler;
+
+ public Return(TResult value, IScheduler scheduler)
+ {
+ _value = value;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>
+ {
+ private readonly Return<TResult> _parent;
+
+ public _(Return<TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ return _parent._scheduler.Schedule(Invoke);
+ }
+
+ private void Invoke()
+ {
+ base._observer.OnNext(_parent._value);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Sample.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Sample.cs
new file mode 100644
index 0000000..0d46c62
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Sample.cs
@@ -0,0 +1,243 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Sample<TSource, TSample> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly IObservable<TSample> _sampler;
+
+ public Sample(IObservable<TSource> source, IObservable<TSample> sampler)
+ {
+ _source = source;
+ _sampler = sampler;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Sample<TSource, TSample> _parent;
+
+ public _(Sample<TSource, TSample> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+
+ private IDisposable _sourceSubscription;
+
+ private bool _hasValue;
+ private TSource _value;
+ private bool _atEnd;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+
+ var sourceSubscription = new SingleAssignmentDisposable();
+ _sourceSubscription = sourceSubscription;
+ sourceSubscription.Disposable = _parent._source.SubscribeSafe(this);
+
+ var samplerSubscription = _parent._sampler.SubscribeSafe(new σ(this));
+
+ return new CompositeDisposable(_sourceSubscription, samplerSubscription);
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ _hasValue = true;
+ _value = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ _atEnd = true;
+ _sourceSubscription.Dispose();
+ }
+ }
+
+ class σ : IObserver<TSample>
+ {
+ private readonly _ _parent;
+
+ public σ(_ parent)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSample value)
+ {
+ lock (_parent._gate)
+ {
+ if (_parent._hasValue)
+ {
+ _parent._hasValue = false;
+ _parent._observer.OnNext(_parent._value);
+ }
+
+ if (_parent._atEnd)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ // BREAKING CHANGE v2 > v1.x - This error used to be swallowed
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ if (_parent._hasValue)
+ {
+ _parent._hasValue = false;
+ _parent._observer.OnNext(_parent._value);
+ }
+
+ if (_parent._atEnd)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ class Sample<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly TimeSpan _interval;
+ private readonly IScheduler _scheduler;
+
+ public Sample(IObservable<TSource> source, TimeSpan interval, IScheduler scheduler)
+ {
+ _source = source;
+ _interval = interval;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Sample<TSource> _parent;
+
+ public _(Sample<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+
+ private IDisposable _sourceSubscription;
+
+ private bool _hasValue;
+ private TSource _value;
+ private bool _atEnd;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+
+ var sourceSubscription = new SingleAssignmentDisposable();
+ _sourceSubscription = sourceSubscription;
+ sourceSubscription.Disposable = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(
+ sourceSubscription,
+ _parent._scheduler.SchedulePeriodic(_parent._interval, Tick)
+ );
+ }
+
+ private void Tick()
+ {
+ lock (_gate)
+ {
+ if (_hasValue)
+ {
+ _hasValue = false;
+ base._observer.OnNext(_value);
+ }
+
+ if (_atEnd)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ _hasValue = true;
+ _value = value;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ _atEnd = true;
+ _sourceSubscription.Dispose();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Scan.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Scan.cs
new file mode 100644
index 0000000..6c8f2fe
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Scan.cs
@@ -0,0 +1,146 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Scan<TSource, TAccumulate> : Producer<TAccumulate>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly TAccumulate _seed;
+ private readonly Func<TAccumulate, TSource, TAccumulate> _accumulator;
+
+ public Scan(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
+ {
+ _source = source;
+ _seed = seed;
+ _accumulator = accumulator;
+ }
+
+ protected override IDisposable Run(IObserver<TAccumulate> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TAccumulate>, IObserver<TSource>
+ {
+ private readonly Scan<TSource, TAccumulate> _parent;
+ private TAccumulate _accumulation;
+ private bool _hasAccumulation;
+
+ public _(Scan<TSource, TAccumulate> parent, IObserver<TAccumulate> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _accumulation = default(TAccumulate);
+ _hasAccumulation = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ try
+ {
+ if (_hasAccumulation)
+ _accumulation = _parent._accumulator(_accumulation, value);
+ else
+ {
+ _accumulation = _parent._accumulator(_parent._seed, value);
+ _hasAccumulation = true;
+ }
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(_accumulation);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class Scan<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TSource, TSource> _accumulator;
+
+ public Scan(IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
+ {
+ _source = source;
+ _accumulator = accumulator;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Scan<TSource> _parent;
+ private TSource _accumulation;
+ private bool _hasAccumulation;
+
+ public _(Scan<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _accumulation = default(TSource);
+ _hasAccumulation = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ try
+ {
+ if (_hasAccumulation)
+ _accumulation = _parent._accumulator(_accumulation, value);
+ else
+ {
+ _accumulation = value;
+ _hasAccumulation = true;
+ }
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(_accumulation);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Select.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Select.cs
new file mode 100644
index 0000000..e853210
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Select.cs
@@ -0,0 +1,138 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ abstract class Select<TResult> : Producer<TResult>
+ {
+ public abstract IObservable<TResult2> Ω<TResult2>(Func<TResult, TResult2> selector);
+ }
+
+ class Select<TSource, TResult> : Select<TResult>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TResult> _selector;
+ private readonly Func<TSource, int, TResult> _selectorI;
+
+ public Select(IObservable<TSource> source, Func<TSource, TResult> selector)
+ {
+ _source = source;
+ _selector = selector;
+ }
+
+ public Select(IObservable<TSource> source, Func<TSource, int, TResult> selector)
+ {
+ _source = source;
+ _selectorI = selector;
+ }
+
+ public override IObservable<TResult2> Ω<TResult2>(Func<TResult, TResult2> selector)
+ {
+ if (_selector != null)
+ return new Select<TSource, TResult2>(_source, x => selector(_selector(x)));
+ else
+ return new Select<TResult, TResult2>(this, selector);
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_selector != null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<TResult>, IObserver<TSource>
+ {
+ private readonly Select<TSource, TResult> _parent;
+
+ public _(Select<TSource, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var result = default(TResult);
+ try
+ {
+ result = _parent._selector(value);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(result);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<TResult>, IObserver<TSource>
+ {
+ private readonly Select<TSource, TResult> _parent;
+ private int _index;
+
+ public τ(Select<TSource, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _index = 0;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var result = default(TResult);
+ try
+ {
+ result = _parent._selectorI(value, checked(_index++));
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(result);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SelectMany.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SelectMany.cs
new file mode 100644
index 0000000..1566816
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SelectMany.cs
@@ -0,0 +1,593 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class SelectMany<TSource, TCollection, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, IObservable<TCollection>> _collectionSelector;
+ private readonly Func<TSource, IEnumerable<TCollection>> _collectionSelectorE;
+ private readonly Func<TSource, TCollection, TResult> _resultSelector;
+
+ public SelectMany(IObservable<TSource> source, Func<TSource, IObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
+ {
+ _source = source;
+ _collectionSelector = collectionSelector;
+ _resultSelector = resultSelector;
+ }
+
+ public SelectMany(IObservable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
+ {
+ _source = source;
+ _collectionSelectorE = collectionSelector;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_collectionSelector != null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new ε(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<TResult>, IObserver<TSource>
+ {
+ private readonly SelectMany<TSource, TCollection, TResult> _parent;
+
+ public _(SelectMany<TSource, TCollection, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private bool _isStopped;
+ private CompositeDisposable _group;
+ private SingleAssignmentDisposable _sourceSubscription;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _isStopped = false;
+ _group = new CompositeDisposable();
+
+ _sourceSubscription = new SingleAssignmentDisposable();
+ _group.Add(_sourceSubscription);
+ _sourceSubscription.Disposable = _parent._source.SubscribeSafe(this);
+
+ return _group;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var collection = default(IObservable<TCollection>);
+
+ try
+ {
+ collection = _parent._collectionSelector(value);
+ }
+ catch (Exception ex)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ return;
+ }
+
+ var innerSubscription = new SingleAssignmentDisposable();
+ _group.Add(innerSubscription);
+ innerSubscription.Disposable = collection.SubscribeSafe(new ι(this, value, innerSubscription));
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _isStopped = true;
+ if (_group.Count == 1)
+ {
+ //
+ // Notice there can be a race between OnCompleted of the source and any
+ // of the inner sequences, where both see _group.Count == 1, and one is
+ // waiting for the lock. There won't be a double OnCompleted observation
+ // though, because the call to Dispose silences the observer by swapping
+ // in a NopObserver<T>.
+ //
+ lock (_gate)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ else
+ {
+ _sourceSubscription.Dispose();
+ }
+ }
+
+ class ι : IObserver<TCollection>
+ {
+ private readonly _ _parent;
+ private readonly TSource _value;
+ private readonly IDisposable _self;
+
+ public ι(_ parent, TSource value, IDisposable self)
+ {
+ _parent = parent;
+ _value = value;
+ _self = self;
+ }
+
+ public void OnNext(TCollection value)
+ {
+ var res = default(TResult);
+
+ try
+ {
+ res = _parent._parent._resultSelector(_value, value);
+ }
+ catch (Exception ex)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(ex);
+ _parent.Dispose();
+ }
+ return;
+ }
+
+ lock (_parent._gate)
+ _parent._observer.OnNext(res);
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _parent._group.Remove(_self);
+ if (_parent._isStopped && _parent._group.Count == 1)
+ {
+ //
+ // Notice there can be a race between OnCompleted of the source and any
+ // of the inner sequences, where both see _group.Count == 1, and one is
+ // waiting for the lock. There won't be a double OnCompleted observation
+ // though, because the call to Dispose silences the observer by swapping
+ // in a NopObserver<T>.
+ //
+ lock (_parent._gate)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+ }
+ }
+
+ class ε : Sink<TResult>, IObserver<TSource>
+ {
+ private readonly SelectMany<TSource, TCollection, TResult> _parent;
+
+ public ε(SelectMany<TSource, TCollection, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var xs = default(IEnumerable<TCollection>);
+ try
+ {
+ xs = _parent._collectionSelectorE(value);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ var e = default(IEnumerator<TCollection>);
+ try
+ {
+ e = xs.GetEnumerator();
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ try
+ {
+ var hasNext = true;
+ while (hasNext)
+ {
+ hasNext = false;
+ var current = default(TResult);
+
+ try
+ {
+ hasNext = e.MoveNext();
+ if (hasNext)
+ current = _parent._resultSelector(value, e.Current);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ if (hasNext)
+ base._observer.OnNext(current);
+ }
+ }
+ finally
+ {
+ if (e != null)
+ e.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class SelectMany<TSource, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, IObservable<TResult>> _selector;
+ private readonly Func<Exception, IObservable<TResult>> _selectorOnError;
+ private readonly Func<IObservable<TResult>> _selectorOnCompleted;
+ private readonly Func<TSource, IEnumerable<TResult>> _selectorE;
+
+ public SelectMany(IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector)
+ {
+ _source = source;
+ _selector = selector;
+ }
+
+ public SelectMany(IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector, Func<Exception, IObservable<TResult>> selectorOnError, Func<IObservable<TResult>> selectorOnCompleted)
+ {
+ _source = source;
+ _selector = selector;
+ _selectorOnError = selectorOnError;
+ _selectorOnCompleted = selectorOnCompleted;
+ }
+
+ public SelectMany(IObservable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
+ {
+ _source = source;
+ _selectorE = selector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_selector != null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new ε(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<TResult>, IObserver<TSource>
+ {
+ private readonly SelectMany<TSource, TResult> _parent;
+
+ public _(SelectMany<TSource, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private bool _isStopped;
+ private CompositeDisposable _group;
+ private SingleAssignmentDisposable _sourceSubscription;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _isStopped = false;
+ _group = new CompositeDisposable();
+
+ _sourceSubscription = new SingleAssignmentDisposable();
+ _group.Add(_sourceSubscription);
+ _sourceSubscription.Disposable = _parent._source.SubscribeSafe(this);
+
+ return _group;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var inner = default(IObservable<TResult>);
+
+ try
+ {
+ inner = _parent._selector(value);
+ }
+ catch (Exception ex)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ return;
+ }
+
+ SubscribeInner(inner);
+ }
+
+ public void OnError(Exception error)
+ {
+ if (_parent._selectorOnError != null)
+ {
+ var inner = default(IObservable<TResult>);
+
+ try
+ {
+ inner = _parent._selectorOnError(error);
+ }
+ catch (Exception ex)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ return;
+ }
+
+ SubscribeInner(inner);
+
+ Final();
+ }
+ else
+ {
+ lock (_gate)
+ base._observer.OnError(error);
+
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ if (_parent._selectorOnCompleted != null)
+ {
+ var inner = default(IObservable<TResult>);
+
+ try
+ {
+ inner = _parent._selectorOnCompleted();
+ }
+ catch (Exception ex)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ return;
+ }
+
+ SubscribeInner(inner);
+ }
+
+ Final();
+ }
+
+ private void Final()
+ {
+ _isStopped = true;
+ if (_group.Count == 1)
+ {
+ //
+ // Notice there can be a race between OnCompleted of the source and any
+ // of the inner sequences, where both see _group.Count == 1, and one is
+ // waiting for the lock. There won't be a double OnCompleted observation
+ // though, because the call to Dispose silences the observer by swapping
+ // in a NopObserver<T>.
+ //
+ lock (_gate)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ else
+ {
+ _sourceSubscription.Dispose();
+ }
+ }
+
+ private void SubscribeInner(IObservable<TResult> inner)
+ {
+ var innerSubscription = new SingleAssignmentDisposable();
+ _group.Add(innerSubscription);
+ innerSubscription.Disposable = inner.SubscribeSafe(new ι(this, innerSubscription));
+ }
+
+ class ι : IObserver<TResult>
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+
+ public ι(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ public void OnNext(TResult value)
+ {
+ lock (_parent._gate)
+ _parent._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _parent._group.Remove(_self);
+ if (_parent._isStopped && _parent._group.Count == 1)
+ {
+ //
+ // Notice there can be a race between OnCompleted of the source and any
+ // of the inner sequences, where both see _group.Count == 1, and one is
+ // waiting for the lock. There won't be a double OnCompleted observation
+ // though, because the call to Dispose silences the observer by swapping
+ // in a NopObserver<T>.
+ //
+ lock (_parent._gate)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+ }
+ }
+
+ class ε : Sink<TResult>, IObserver<TSource>
+ {
+ private readonly SelectMany<TSource, TResult> _parent;
+
+ public ε(SelectMany<TSource, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var xs = default(IEnumerable<TResult>);
+ try
+ {
+ xs = _parent._selectorE(value);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ var e = default(IEnumerator<TResult>);
+ try
+ {
+ e = xs.GetEnumerator();
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ try
+ {
+ var hasNext = true;
+ while (hasNext)
+ {
+ hasNext = false;
+ var current = default(TResult);
+
+ try
+ {
+ hasNext = e.MoveNext();
+ if (hasNext)
+ current = e.Current;
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ if (hasNext)
+ base._observer.OnNext(current);
+ }
+ }
+ finally
+ {
+ if (e != null)
+ e.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SequenceEqual.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SequenceEqual.cs
new file mode 100644
index 0000000..4661f82
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SequenceEqual.cs
@@ -0,0 +1,322 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class SequenceEqual<TSource> : Producer<bool>
+ {
+ private readonly IObservable<TSource> _first;
+ private readonly IObservable<TSource> _second;
+ private readonly IEnumerable<TSource> _secondE;
+ private readonly IEqualityComparer<TSource> _comparer;
+
+ public SequenceEqual(IObservable<TSource> first, IObservable<TSource> second, IEqualityComparer<TSource> comparer)
+ {
+ _first = first;
+ _second = second;
+ _comparer = comparer;
+ }
+
+ public SequenceEqual(IObservable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
+ {
+ _first = first;
+ _secondE = second;
+ _comparer = comparer;
+ }
+
+ protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_second != null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new ε(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<bool>
+ {
+ private readonly SequenceEqual<TSource> _parent;
+
+ public _(SequenceEqual<TSource> parent, IObserver<bool> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private bool _donel;
+ private bool _doner;
+ private Queue<TSource> _ql;
+ private Queue<TSource> _qr;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _donel = false;
+ _doner = false;
+ _ql = new Queue<TSource>();
+ _qr = new Queue<TSource>();
+
+ return new CompositeDisposable
+ {
+ _parent._first.SubscribeSafe(new F(this)),
+ _parent._second.SubscribeSafe(new S(this))
+ };
+ }
+
+ class F : IObserver<TSource>
+ {
+ private readonly _ _parent;
+
+ public F(_ parent)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_parent._gate)
+ {
+ if (_parent._qr.Count > 0)
+ {
+ var equal = false;
+ var v = _parent._qr.Dequeue();
+ try
+ {
+ equal = _parent._parent._comparer.Equals(value, v);
+ }
+ catch (Exception exception)
+ {
+ _parent._observer.OnError(exception);
+ _parent.Dispose();
+ return;
+ }
+ if (!equal)
+ {
+ _parent._observer.OnNext(false);
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ else if (_parent._doner)
+ {
+ _parent._observer.OnNext(false);
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ else
+ _parent._ql.Enqueue(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ _parent._donel = true;
+ if (_parent._ql.Count == 0)
+ {
+ if (_parent._qr.Count > 0)
+ {
+ _parent._observer.OnNext(false);
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ else if (_parent._doner)
+ {
+ _parent._observer.OnNext(true);
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+ }
+ }
+
+ class S : IObserver<TSource>
+ {
+ private readonly _ _parent;
+
+ public S(_ parent)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_parent._gate)
+ {
+ if (_parent._ql.Count > 0)
+ {
+ var equal = false;
+ var v = _parent._ql.Dequeue();
+ try
+ {
+ equal = _parent._parent._comparer.Equals(v, value);
+ }
+ catch (Exception exception)
+ {
+ _parent._observer.OnError(exception);
+ _parent.Dispose();
+ return;
+ }
+ if (!equal)
+ {
+ _parent._observer.OnNext(false);
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ else if (_parent._donel)
+ {
+ _parent._observer.OnNext(false);
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ else
+ _parent._qr.Enqueue(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ _parent._doner = true;
+ if (_parent._qr.Count == 0)
+ {
+ if (_parent._ql.Count > 0)
+ {
+ _parent._observer.OnNext(false);
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ else if (_parent._donel)
+ {
+ _parent._observer.OnNext(true);
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ class ε : Sink<bool>, IObserver<TSource>
+ {
+ private readonly SequenceEqual<TSource> _parent;
+
+ public ε(SequenceEqual<TSource> parent, IObserver<bool> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private IEnumerator<TSource> _enumerator;
+
+ public IDisposable Run()
+ {
+ //
+ // Notice the evaluation order of obtaining the enumerator and subscribing to the
+ // observable sequence is reversed compared to the operator's signature. This is
+ // required to make sure the enumerator is available as soon as the observer can
+ // be called. Otherwise, we end up having a race for the initialization and use
+ // of the _rightEnumerator field.
+ //
+ try
+ {
+ _enumerator = _parent._secondE.GetEnumerator();
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ return new CompositeDisposable(
+ _parent._first.SubscribeSafe(this),
+ _enumerator
+ );
+ }
+
+ public void OnNext(TSource value)
+ {
+ var equal = false;
+
+ try
+ {
+ if (_enumerator.MoveNext())
+ {
+ var current = _enumerator.Current;
+ equal = _parent._comparer.Equals(value, current);
+ }
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ if (!equal)
+ {
+ base._observer.OnNext(false);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ var hasNext = false;
+
+ try
+ {
+ hasNext = _enumerator.MoveNext();
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(!hasNext);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SingleAsync.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SingleAsync.cs
new file mode 100644
index 0000000..19c07e5
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SingleAsync.cs
@@ -0,0 +1,154 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class SingleAsync<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+ private readonly bool _throwOnEmpty;
+
+ public SingleAsync(IObservable<TSource> source, Func<TSource, bool> predicate, bool throwOnEmpty)
+ {
+ _source = source;
+ _predicate = predicate;
+ _throwOnEmpty = throwOnEmpty;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_predicate != null)
+ {
+ var sink = new π(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly SingleAsync<TSource> _parent;
+ private TSource _value;
+ private bool _seenValue;
+
+ public _(SingleAsync<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+
+ _value = default(TSource);
+ _seenValue = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_seenValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_ELEMENT));
+ base.Dispose();
+ return;
+ }
+
+ _value = value;
+ _seenValue = true;
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_seenValue && _parent._throwOnEmpty)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_value);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+
+ class π : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly SingleAsync<TSource> _parent;
+ private TSource _value;
+ private bool _seenValue;
+
+ public π(SingleAsync<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+
+ _value = default(TSource);
+ _seenValue = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var b = false;
+
+ try
+ {
+ b = _parent._predicate(value);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (b)
+ {
+ if (_seenValue)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_MATCHING_ELEMENT));
+ base.Dispose();
+ return;
+ }
+
+ _value = value;
+ _seenValue = true;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ if (!_seenValue && _parent._throwOnEmpty)
+ {
+ base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_MATCHING_ELEMENTS));
+ }
+ else
+ {
+ base._observer.OnNext(_value);
+ base._observer.OnCompleted();
+ }
+
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Skip.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Skip.cs
new file mode 100644
index 0000000..a092d99
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Skip.cs
@@ -0,0 +1,151 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Skip<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly int _count;
+ private readonly TimeSpan _duration;
+ internal readonly IScheduler _scheduler;
+
+ public Skip(IObservable<TSource> source, int count)
+ {
+ _source = source;
+ _count = count;
+ }
+
+ public Skip(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ _source = source;
+ _duration = duration;
+ _scheduler = scheduler;
+ }
+
+ public IObservable<TSource> Ω(int count)
+ {
+ //
+ // Sum semantics:
+ //
+ // xs --o--o--o--o--o--o--| xs --o--o--o--o--o--o--|
+ // xs.Skip(2) --x--x--o--o--o--o--| xs.Skip(3) --x--x--x--o--o--o--|
+ // xs.Skip(2).Skip(3) --------x--x--x--o--| xs.Skip(3).Skip(2) -----------x--x--o--|
+ //
+ return new Skip<TSource>(_source, _count + count);
+ }
+
+ public IObservable<TSource> Ω(TimeSpan duration)
+ {
+ //
+ // Maximum semantics:
+ //
+ // t 0--1--2--3--4--5--6--7-> t 0--1--2--3--4--5--6--7->
+ //
+ // xs --o--o--o--o--o--o--| xs --o--o--o--o--o--o--|
+ // xs.Skip(2s) xxxxxxx-o--o--o--o--| xs.Skip(3s) xxxxxxxxxx-o--o--o--|
+ // xs.Skip(2s).Skip(3s) xxxxxxxxxx-o--o--o--| xs.Skip(3s).Skip(2s) xxxxxxx----o--o--o--|
+ //
+ if (duration <= _duration)
+ return this;
+ else
+ return new Skip<TSource>(_source, duration, _scheduler);
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_scheduler == null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Skip<TSource> _parent;
+ private int _remaining;
+
+ public _(Skip<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _remaining = _parent._count;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_remaining <= 0)
+ base._observer.OnNext(value);
+ else
+ _remaining--;
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Skip<TSource> _parent;
+ private volatile bool _open;
+
+ public τ(Skip<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var t = _parent._scheduler.Schedule(_parent._duration, Tick);
+ var d = _parent._source.SubscribeSafe(this);
+ return new CompositeDisposable(t, d);
+ }
+
+ private void Tick()
+ {
+ _open = true;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_open)
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipLast.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipLast.cs
new file mode 100644
index 0000000..596f183
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipLast.cs
@@ -0,0 +1,125 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class SkipLast<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly int _count;
+ private readonly TimeSpan _duration;
+ private readonly IScheduler _scheduler;
+
+ public SkipLast(IObservable<TSource> source, int count)
+ {
+ _source = source;
+ _count = count;
+ }
+
+ public SkipLast(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ _source = source;
+ _duration = duration;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_scheduler == null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly SkipLast<TSource> _parent;
+ private Queue<TSource> _queue;
+
+ public _(SkipLast<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _queue = new Queue<TSource>();
+ }
+
+ public void OnNext(TSource value)
+ {
+ _queue.Enqueue(value);
+ if (_queue.Count > _parent._count)
+ base._observer.OnNext(_queue.Dequeue());
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly SkipLast<TSource> _parent;
+ private Queue<System.Reactive.TimeInterval<TSource>> _queue;
+
+ public τ(SkipLast<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _queue = new Queue<System.Reactive.TimeInterval<TSource>>();
+ }
+
+ private IStopwatch _watch;
+
+ public IDisposable Run()
+ {
+ _watch = _parent._scheduler.StartStopwatch();
+
+ return _parent._source.SubscribeSafe(this);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var now = _watch.Elapsed;
+ _queue.Enqueue(new System.Reactive.TimeInterval<TSource>(value, now));
+ while (_queue.Count > 0 && now - _queue.Peek().Interval >= _parent._duration)
+ base._observer.OnNext(_queue.Dequeue().Value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ var now = _watch.Elapsed;
+ while (_queue.Count > 0 && now - _queue.Peek().Interval >= _parent._duration)
+ base._observer.OnNext(_queue.Dequeue().Value);
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipUntil.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipUntil.cs
new file mode 100644
index 0000000..8d4c7a9
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipUntil.cs
@@ -0,0 +1,210 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class SkipUntil<TSource, TOther> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly IObservable<TOther> _other;
+
+ public SkipUntil(IObservable<TSource> source, IObservable<TOther> other)
+ {
+ _source = source;
+ _other = other;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>
+ {
+ private readonly SkipUntil<TSource, TOther> _parent;
+
+ public _(SkipUntil<TSource, TOther> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var sourceObserver = new T(this);
+ var otherObserver = new O(this, sourceObserver);
+
+ var sourceSubscription = _parent._source.SubscribeSafe(sourceObserver);
+ var otherSubscription = _parent._other.SubscribeSafe(otherObserver);
+
+ sourceObserver.Disposable = sourceSubscription;
+ otherObserver.Disposable = otherSubscription;
+
+ return new CompositeDisposable(
+ sourceSubscription,
+ otherSubscription
+ );
+ }
+
+ class T : IObserver<TSource>
+ {
+ private readonly _ _parent;
+ public volatile IObserver<TSource> _observer;
+ private readonly SingleAssignmentDisposable _subscription;
+
+ public T(_ parent)
+ {
+ _parent = parent;
+ _observer = NopObserver<TSource>.Instance;
+ _subscription = new SingleAssignmentDisposable();
+ }
+
+ public IDisposable Disposable
+ {
+ set { _subscription.Disposable = value; }
+ }
+
+ public void OnNext(TSource value)
+ {
+ _observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ _observer.OnCompleted();
+ _subscription.Dispose(); // We can't cancel the other stream yet, it may be on its way to dispatch an OnError message and we don't want to have a race.
+ }
+ }
+
+ class O : IObserver<TOther>
+ {
+ private readonly _ _parent;
+ private readonly T _sourceObserver;
+ private readonly SingleAssignmentDisposable _subscription;
+
+ public O(_ parent, T sourceObserver)
+ {
+ _parent = parent;
+ _sourceObserver = sourceObserver;
+ _subscription = new SingleAssignmentDisposable();
+ }
+
+ public IDisposable Disposable
+ {
+ set { _subscription.Disposable = value; }
+ }
+
+ public void OnNext(TOther value)
+ {
+ _sourceObserver._observer = _parent._observer;
+ _subscription.Dispose();
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ _subscription.Dispose();
+ }
+ }
+ }
+ }
+
+ class SkipUntil<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly DateTimeOffset _startTime;
+ internal readonly IScheduler _scheduler;
+
+ public SkipUntil(IObservable<TSource> source, DateTimeOffset startTime, IScheduler scheduler)
+ {
+ _source = source;
+ _startTime = startTime;
+ _scheduler = scheduler;
+ }
+
+ public IObservable<TSource> Ω(DateTimeOffset startTime)
+ {
+ //
+ // Maximum semantics:
+ //
+ // t 0--1--2--3--4--5--6--7-> t 0--1--2--3--4--5--6--7->
+ //
+ // xs --o--o--o--o--o--o--| xs --o--o--o--o--o--o--|
+ // xs.SU(5AM) xxxxxxxxxxxxxxxx-o--| xs.SU(3AM) xxxxxxxxxx-o--o--o--|
+ // xs.SU(5AM).SU(3AM) xxxxxxxxx--------o--| xs.SU(3AM).SU(5AM) xxxxxxxxxxxxxxxx-o--|
+ //
+ if (startTime <= _startTime)
+ return this;
+ else
+ return new SkipUntil<TSource>(_source, startTime, _scheduler);
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly SkipUntil<TSource> _parent;
+ private volatile bool _open;
+
+ public _(SkipUntil<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var t = _parent._scheduler.Schedule(_parent._startTime, Tick);
+ var d = _parent._source.SubscribeSafe(this);
+ return new CompositeDisposable(t, d);
+ }
+
+ private void Tick()
+ {
+ _open = true;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_open)
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipWhile.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipWhile.cs
new file mode 100644
index 0000000..e6e379d
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipWhile.cs
@@ -0,0 +1,139 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class SkipWhile<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+ private readonly Func<TSource, int, bool> _predicateI;
+
+ public SkipWhile(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ _source = source;
+ _predicate = predicate;
+ }
+
+ public SkipWhile(IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+ _source = source;
+ _predicateI = predicate;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_predicate != null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly SkipWhile<TSource> _parent;
+ private bool _running;
+
+ public _(SkipWhile<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _running = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (!_running)
+ {
+ try
+ {
+ _running = !_parent._predicate(value);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+ }
+
+ if (_running)
+ {
+ base._observer.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly SkipWhile<TSource> _parent;
+ private bool _running;
+ private int _index;
+
+ public τ(SkipWhile<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _running = false;
+ _index = 0;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (!_running)
+ {
+ try
+ {
+ _running = !_parent._predicateI(value, checked(_index++));
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+ }
+
+ if (_running)
+ {
+ base._observer.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Sum.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Sum.cs
new file mode 100644
index 0000000..6d51153
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Sum.cs
@@ -0,0 +1,517 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class SumDouble : Producer<double>
+ {
+ private readonly IObservable<double> _source;
+
+ public SumDouble(IObservable<double> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double>, IObserver<double>
+ {
+ private double _sum;
+
+ public _(IObserver<double> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0.0;
+ }
+
+ public void OnNext(double value)
+ {
+ _sum += value;
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_sum);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class SumSingle : Producer<float>
+ {
+ private readonly IObservable<float> _source;
+
+ public SumSingle(IObservable<float> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<float> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<float>, IObserver<float>
+ {
+ private double _sum; // This is what LINQ to Objects does!
+
+ public _(IObserver<float> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0.0; // This is what LINQ to Objects does!
+ }
+
+ public void OnNext(float value)
+ {
+ _sum += value; // This is what LINQ to Objects does!
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext((float)_sum); // This is what LINQ to Objects does!
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class SumDecimal : Producer<decimal>
+ {
+ private readonly IObservable<decimal> _source;
+
+ public SumDecimal(IObservable<decimal> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<decimal> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<decimal>, IObserver<decimal>
+ {
+ private decimal _sum;
+
+ public _(IObserver<decimal> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0M;
+ }
+
+ public void OnNext(decimal value)
+ {
+ _sum += value;
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_sum);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class SumInt32 : Producer<int>
+ {
+ private readonly IObservable<int> _source;
+
+ public SumInt32(IObservable<int> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<int>, IObserver<int>
+ {
+ private int _sum;
+
+ public _(IObserver<int> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0;
+ }
+
+ public void OnNext(int value)
+ {
+ try
+ {
+ checked
+ {
+ _sum += value;
+ }
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_sum);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class SumInt64 : Producer<long>
+ {
+ private readonly IObservable<long> _source;
+
+ public SumInt64(IObservable<long> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<long>, IObserver<long>
+ {
+ private long _sum;
+
+ public _(IObserver<long> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0L;
+ }
+
+ public void OnNext(long value)
+ {
+ try
+ {
+ checked
+ {
+ _sum += value;
+ }
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_sum);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class SumDoubleNullable : Producer<double?>
+ {
+ private readonly IObservable<double?> _source;
+
+ public SumDoubleNullable(IObservable<double?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<double?>, IObserver<double?>
+ {
+ private double _sum;
+
+ public _(IObserver<double?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0.0;
+ }
+
+ public void OnNext(double? value)
+ {
+ if (value != null)
+ _sum += value.Value;
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_sum);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class SumSingleNullable : Producer<float?>
+ {
+ private readonly IObservable<float?> _source;
+
+ public SumSingleNullable(IObservable<float?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<float?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<float?>, IObserver<float?>
+ {
+ private double _sum; // This is what LINQ to Objects does!
+
+ public _(IObserver<float?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0.0; // This is what LINQ to Objects does!
+ }
+
+ public void OnNext(float? value)
+ {
+ if (value != null)
+ _sum += value.Value; // This is what LINQ to Objects does!
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext((float)_sum); // This is what LINQ to Objects does!
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class SumDecimalNullable : Producer<decimal?>
+ {
+ private readonly IObservable<decimal?> _source;
+
+ public SumDecimalNullable(IObservable<decimal?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<decimal?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<decimal?>, IObserver<decimal?>
+ {
+ private decimal _sum;
+
+ public _(IObserver<decimal?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0M;
+ }
+
+ public void OnNext(decimal? value)
+ {
+ if (value != null)
+ _sum += value.Value;
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_sum);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class SumInt32Nullable : Producer<int?>
+ {
+ private readonly IObservable<int?> _source;
+
+ public SumInt32Nullable(IObservable<int?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<int?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<int?>, IObserver<int?>
+ {
+ private int _sum;
+
+ public _(IObserver<int?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0;
+ }
+
+ public void OnNext(int? value)
+ {
+ try
+ {
+ checked
+ {
+ if (value != null)
+ _sum += value.Value;
+ }
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_sum);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class SumInt64Nullable : Producer<long?>
+ {
+ private readonly IObservable<long?> _source;
+
+ public SumInt64Nullable(IObservable<long?> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<long?> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<long?>, IObserver<long?>
+ {
+ private long _sum;
+
+ public _(IObserver<long?> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _sum = 0L;
+ }
+
+ public void OnNext(long? value)
+ {
+ try
+ {
+ checked
+ {
+ if (value != null)
+ _sum += value.Value;
+ }
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_sum);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Switch.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Switch.cs
new file mode 100644
index 0000000..794b0d4
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Switch.cs
@@ -0,0 +1,152 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Switch<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<IObservable<TSource>> _sources;
+
+ public Switch(IObservable<IObservable<TSource>> sources)
+ {
+ _sources = sources;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<IObservable<TSource>>
+ {
+ private readonly Switch<TSource> _parent;
+
+ public _(Switch<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private IDisposable _subscription;
+ private SerialDisposable _innerSubscription;
+ private bool _isStopped;
+ private ulong _latest;
+ private bool _hasLatest;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _innerSubscription = new SerialDisposable();
+ _isStopped = false;
+ _latest = 0UL;
+ _hasLatest = false;
+
+ var subscription = new SingleAssignmentDisposable();
+ _subscription = subscription;
+ subscription.Disposable = _parent._sources.SubscribeSafe(this);
+
+ return new CompositeDisposable(_subscription, _innerSubscription);
+ }
+
+ public void OnNext(IObservable<TSource> value)
+ {
+ var id = default(ulong);
+ lock (_gate)
+ {
+ id = unchecked(++_latest);
+ _hasLatest = true;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ _innerSubscription.Disposable = d;
+ d.Disposable = value.SubscribeSafe(new ι(this, id, d));
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ base._observer.OnError(error);
+
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ _subscription.Dispose();
+
+ _isStopped = true;
+ if (!_hasLatest)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class ι : IObserver<TSource>
+ {
+ private readonly _ _parent;
+ private readonly ulong _id;
+ private readonly IDisposable _self;
+
+ public ι(_ parent, ulong id, IDisposable self)
+ {
+ _parent = parent;
+ _id = id;
+ _self = self;
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_parent._gate)
+ {
+ if (_parent._latest == _id)
+ _parent._observer.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _self.Dispose();
+
+ if (_parent._latest == _id)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ _self.Dispose();
+
+ if (_parent._latest == _id)
+ {
+ _parent._hasLatest = false;
+
+ if (_parent._isStopped)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Synchronize.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Synchronize.cs
new file mode 100644
index 0000000..cb4e3d9
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Synchronize.cs
@@ -0,0 +1,69 @@
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Synchronize<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly object _gate;
+
+ public Synchronize(IObservable<TSource> source, object gate)
+ {
+ _source = source;
+ _gate = gate;
+ }
+
+ public Synchronize(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.Subscribe(sink);
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Synchronize<TSource> _parent;
+ private object _gate;
+
+ public _(Synchronize<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _gate = _parent._gate ?? new object();
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ base._observer.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Take.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Take.cs
new file mode 100644
index 0000000..738e7c0
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Take.cs
@@ -0,0 +1,176 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Take<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly int _count;
+ private readonly TimeSpan _duration;
+ internal readonly IScheduler _scheduler;
+
+ public Take(IObservable<TSource> source, int count)
+ {
+ _source = source;
+ _count = count;
+ }
+
+ public Take(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ _source = source;
+ _duration = duration;
+ _scheduler = scheduler;
+ }
+
+ public IObservable<TSource> Ω(int count)
+ {
+ //
+ // Minimum semantics:
+ //
+ // xs --o--o--o--o--o--o--| xs --o--o--o--o--o--o--|
+ // xs.Take(5) --o--o--o--o--o| xs.Take(3) --o--o--o|
+ // xs.Take(5).Take(3) --o--o--o| xs.Take(3).Take(5) --o--o--o|
+ //
+ if (_count <= count)
+ return this;
+ else
+ return new Take<TSource>(_source, count);
+ }
+
+ public IObservable<TSource> Ω(TimeSpan duration)
+ {
+ //
+ // Minimum semantics:
+ //
+ // t 0--1--2--3--4--5--6--7-> t 0--1--2--3--4--5--6--7->
+ //
+ // xs --o--o--o--o--o--o--| xs --o--o--o--o--o--o--|
+ // xs.Take(5s) --o--o--o--o--o| xs.Take(3s) --o--o--o|
+ // xs.Take(5s).Take(3s) --o--o--o| xs.Take(3s).Take(5s) --o--o--o|
+ //
+ if (_duration <= duration)
+ return this;
+ else
+ return new Take<TSource>(_source, duration, _scheduler);
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_scheduler == null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Take<TSource> _parent;
+ private int _remaining;
+
+ public _(Take<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _remaining = _parent._count;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_remaining > 0)
+ {
+ --_remaining;
+ base._observer.OnNext(value);
+
+ if (_remaining == 0)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Take<TSource> _parent;
+
+ public τ(Take<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+
+ var t = _parent._scheduler.Schedule(_parent._duration, Tick);
+ var d = _parent._source.SubscribeSafe(this);
+ return new CompositeDisposable(t, d);
+ }
+
+ private void Tick()
+ {
+ lock (_gate)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ base._observer.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeLast.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeLast.cs
new file mode 100644
index 0000000..98bf40e
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeLast.cs
@@ -0,0 +1,230 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class TakeLast<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly int _count;
+ private readonly TimeSpan _duration;
+ private readonly IScheduler _scheduler;
+ private readonly IScheduler _loopScheduler;
+
+ public TakeLast(IObservable<TSource> source, int count, IScheduler loopScheduler)
+ {
+ _source = source;
+ _count = count;
+ _loopScheduler = loopScheduler;
+ }
+
+ public TakeLast(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler, IScheduler loopScheduler)
+ {
+ _source = source;
+ _duration = duration;
+ _scheduler = scheduler;
+ _loopScheduler = loopScheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_scheduler == null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly TakeLast<TSource> _parent;
+ private Queue<TSource> _queue;
+
+ public _(TakeLast<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _queue = new Queue<TSource>();
+ }
+
+ private SingleAssignmentDisposable _subscription;
+ private SingleAssignmentDisposable _loop;
+
+ public IDisposable Run()
+ {
+ _subscription = new SingleAssignmentDisposable();
+ _loop = new SingleAssignmentDisposable();
+
+ _subscription.Disposable = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(_subscription, _loop);
+ }
+
+ public void OnNext(TSource value)
+ {
+ _queue.Enqueue(value);
+ if (_queue.Count > _parent._count)
+ _queue.Dequeue();
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ _subscription.Dispose();
+
+ var longRunning = _parent._loopScheduler.AsLongRunning();
+ if (longRunning != null)
+ _loop.Disposable = longRunning.ScheduleLongRunning(Loop);
+ else
+ _loop.Disposable = _parent._loopScheduler.Schedule(LoopRec);
+ }
+
+ private void LoopRec(Action recurse)
+ {
+ if (_queue.Count > 0)
+ {
+ base._observer.OnNext(_queue.Dequeue());
+ recurse();
+ }
+ else
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ private void Loop(ICancelable cancel)
+ {
+ var n = _queue.Count;
+
+ while (!cancel.IsDisposed)
+ {
+ if (n == 0)
+ {
+ base._observer.OnCompleted();
+ break;
+ }
+ else
+ base._observer.OnNext(_queue.Dequeue());
+
+ n--;
+ }
+
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly TakeLast<TSource> _parent;
+ private Queue<System.Reactive.TimeInterval<TSource>> _queue;
+
+ public τ(TakeLast<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _queue = new Queue<System.Reactive.TimeInterval<TSource>>();
+ }
+
+ private SingleAssignmentDisposable _subscription;
+ private SingleAssignmentDisposable _loop;
+ private IStopwatch _watch;
+
+ public IDisposable Run()
+ {
+ _subscription = new SingleAssignmentDisposable();
+ _loop = new SingleAssignmentDisposable();
+
+ _watch = _parent._scheduler.StartStopwatch();
+ _subscription.Disposable = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(_subscription, _loop);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var now = _watch.Elapsed;
+ _queue.Enqueue(new System.Reactive.TimeInterval<TSource>(value, now));
+ Trim(now);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ _subscription.Dispose();
+
+ var now = _watch.Elapsed;
+ Trim(now);
+
+ var longRunning = _parent._loopScheduler.AsLongRunning();
+ if (longRunning != null)
+ _loop.Disposable = longRunning.ScheduleLongRunning(Loop);
+ else
+ _loop.Disposable = _parent._loopScheduler.Schedule(LoopRec);
+ }
+
+ private void LoopRec(Action recurse)
+ {
+ if (_queue.Count > 0)
+ {
+ base._observer.OnNext(_queue.Dequeue().Value);
+ recurse();
+ }
+ else
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ private void Loop(ICancelable cancel)
+ {
+ var n = _queue.Count;
+
+ while (!cancel.IsDisposed)
+ {
+ if (n == 0)
+ {
+ base._observer.OnCompleted();
+ break;
+ }
+ else
+ base._observer.OnNext(_queue.Dequeue().Value);
+
+ n--;
+ }
+
+ base.Dispose();
+ }
+
+ private void Trim(TimeSpan now)
+ {
+ while (_queue.Count > 0 && now - _queue.Peek().Interval >= _parent._duration)
+ _queue.Dequeue();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeLastBuffer.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeLastBuffer.cs
new file mode 100644
index 0000000..71b36b0
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeLastBuffer.cs
@@ -0,0 +1,141 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class TakeLastBuffer<TSource> : Producer<IList<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly int _count;
+ private readonly TimeSpan _duration;
+ private readonly IScheduler _scheduler;
+
+ public TakeLastBuffer(IObservable<TSource> source, int count)
+ {
+ _source = source;
+ _count = count;
+ }
+
+ public TakeLastBuffer(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ _source = source;
+ _duration = duration;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_scheduler == null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private readonly TakeLastBuffer<TSource> _parent;
+ private Queue<TSource> _queue;
+
+ public _(TakeLastBuffer<TSource> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _queue = new Queue<TSource>();
+ }
+
+ public void OnNext(TSource value)
+ {
+ _queue.Enqueue(value);
+ if (_queue.Count > _parent._count)
+ _queue.Dequeue();
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ var res = new List<TSource>(_queue.Count);
+ while (_queue.Count > 0)
+ res.Add(_queue.Dequeue());
+
+ base._observer.OnNext(res);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private readonly TakeLastBuffer<TSource> _parent;
+ private Queue<System.Reactive.TimeInterval<TSource>> _queue;
+
+ public τ(TakeLastBuffer<TSource> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _queue = new Queue<System.Reactive.TimeInterval<TSource>>();
+ }
+
+ private IStopwatch _watch;
+
+ public IDisposable Run()
+ {
+ _watch = _parent._scheduler.StartStopwatch();
+
+ return _parent._source.SubscribeSafe(this);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var now = _watch.Elapsed;
+ _queue.Enqueue(new System.Reactive.TimeInterval<TSource>(value, now));
+ Trim(now);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ var now = _watch.Elapsed;
+ Trim(now);
+
+ var res = new List<TSource>(_queue.Count);
+ while (_queue.Count > 0)
+ res.Add(_queue.Dequeue().Value);
+
+ base._observer.OnNext(res);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+
+ private void Trim(TimeSpan now)
+ {
+ while (_queue.Count > 0 && now - _queue.Peek().Interval >= _parent._duration)
+ _queue.Dequeue();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeUntil.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeUntil.cs
new file mode 100644
index 0000000..eccc222
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeUntil.cs
@@ -0,0 +1,258 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class TakeUntil<TSource, TOther> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly IObservable<TOther> _other;
+
+ public TakeUntil(IObservable<TSource> source, IObservable<TOther> other)
+ {
+ _source = source;
+ _other = other;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>
+ {
+ private readonly TakeUntil<TSource, TOther> _parent;
+
+ public _(TakeUntil<TSource, TOther> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var sourceObserver = new T(this);
+ var otherObserver = new O(this, sourceObserver);
+
+ // COMPAT - Order of Subscribe calls per v1.0.10621
+ var otherSubscription = _parent._other.SubscribeSafe(otherObserver);
+ otherObserver.Disposable = otherSubscription;
+
+ var sourceSubscription = _parent._source.SubscribeSafe(sourceObserver);
+
+ return new CompositeDisposable(
+ otherSubscription,
+ sourceSubscription
+ );
+ }
+
+ /*
+ * We tried a more fine-grained synchronization scheme to make TakeUntil more efficient, but
+ * this requires several CAS instructions, which quickly add up to being non-beneficial.
+ *
+ * Notice an approach where the "other" channel performs an Interlocked.Exchange operation on
+ * the _parent._observer field to substitute it with a NopObserver<TSource> doesn't work,
+ * because the "other" channel still need to send an OnCompleted message, which could happen
+ * concurrently with another message when the "source" channel has already read from the
+ * _parent._observer field between making the On* call.
+ *
+ * Fixing this issue requires an ownership transfer mechanism for channels to get exclusive
+ * access to the outgoing observer while dispatching a message. Doing this more fine-grained
+ * than using locks turns out to be tricky and doesn't reduce cost.
+ */
+ class T : IObserver<TSource>
+ {
+ private readonly _ _parent;
+ public volatile bool _open;
+
+ public T(_ parent)
+ {
+ _parent = parent;
+ _open = false;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_open)
+ {
+ _parent._observer.OnNext(value);
+ }
+ else
+ {
+ lock (_parent)
+ {
+ _parent._observer.OnNext(value);
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+ }
+
+ class O : IObserver<TOther>
+ {
+ private readonly _ _parent;
+ private readonly T _sourceObserver;
+ private readonly SingleAssignmentDisposable _subscription;
+
+ public O(_ parent, T sourceObserver)
+ {
+ _parent = parent;
+ _sourceObserver = sourceObserver;
+ _subscription = new SingleAssignmentDisposable();
+ }
+
+ public IDisposable Disposable
+ {
+ set { _subscription.Disposable = value; }
+ }
+
+ public void OnNext(TOther value)
+ {
+ lock (_parent)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent)
+ {
+ _sourceObserver._open = true;
+ _subscription.Dispose();
+ }
+ }
+ }
+ }
+ }
+
+ class TakeUntil<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly DateTimeOffset _endTime;
+ internal readonly IScheduler _scheduler;
+
+ public TakeUntil(IObservable<TSource> source, DateTimeOffset endTime, IScheduler scheduler)
+ {
+ _source = source;
+ _endTime = endTime;
+ _scheduler = scheduler;
+ }
+
+ public IObservable<TSource> Ω(DateTimeOffset endTime)
+ {
+ //
+ // Minimum semantics:
+ //
+ // t 0--1--2--3--4--5--6--7-> t 0--1--2--3--4--5--6--7->
+ //
+ // xs --o--o--o--o--o--o--| xs --o--o--o--o--o--o--|
+ // xs.TU(5AM) --o--o--o--o--o| xs.TU(3AM) --o--o--o|
+ // xs.TU(5AM).TU(3AM) --o--o--o| xs.TU(3AM).TU(5AM) --o--o--o|
+ //
+ if (_endTime <= endTime)
+ return this;
+ else
+ return new TakeUntil<TSource>(_source, endTime, _scheduler);
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly TakeUntil<TSource> _parent;
+
+ public _(TakeUntil<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+
+ var t = _parent._scheduler.Schedule(_parent._endTime, Tick);
+ var d = _parent._source.SubscribeSafe(this);
+ return new CompositeDisposable(t, d);
+ }
+
+ private void Tick()
+ {
+ lock (_gate)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ base._observer.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeWhile.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeWhile.cs
new file mode 100644
index 0000000..30f63ca
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeWhile.cs
@@ -0,0 +1,149 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class TakeWhile<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+ private readonly Func<TSource, int, bool> _predicateI;
+
+ public TakeWhile(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ _source = source;
+ _predicate = predicate;
+ }
+
+ public TakeWhile(IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+ _source = source;
+ _predicateI = predicate;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_predicate != null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly TakeWhile<TSource> _parent;
+ private bool _running;
+
+ public _(TakeWhile<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _running = true;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_running)
+ {
+ try
+ {
+ _running = _parent._predicate(value);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ if (_running)
+ {
+ base._observer.OnNext(value);
+ }
+ else
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly TakeWhile<TSource> _parent;
+ private bool _running;
+ private int _index;
+
+ public τ(TakeWhile<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _running = true;
+ _index = 0;
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (_running)
+ {
+ try
+ {
+ _running = _parent._predicateI(value, checked(_index++));
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ if (_running)
+ {
+ base._observer.OnNext(value);
+ }
+ else
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Throttle.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Throttle.cs
new file mode 100644
index 0000000..7b7ad86
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Throttle.cs
@@ -0,0 +1,280 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Throttle<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly TimeSpan _dueTime;
+ private readonly IScheduler _scheduler;
+
+ public Throttle(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ _source = source;
+ _dueTime = dueTime;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Throttle<TSource> _parent;
+
+ public _(Throttle<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private TSource _value;
+ private bool _hasValue;
+ private SerialDisposable _cancelable;
+ private ulong _id;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _value = default(TSource);
+ _hasValue = false;
+ _cancelable = new SerialDisposable();
+ _id = 0UL;
+
+ var subscription = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(subscription, _cancelable);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var currentid = default(ulong);
+ lock (_gate)
+ {
+ _hasValue = true;
+ _value = value;
+ _id = unchecked(_id + 1);
+ currentid = _id;
+ }
+ var d = new SingleAssignmentDisposable();
+ _cancelable.Disposable = d;
+ d.Disposable = _parent._scheduler.Schedule(currentid, _parent._dueTime, Propagate);
+ }
+
+ private IDisposable Propagate(IScheduler self, ulong currentid)
+ {
+ lock (_gate)
+ {
+ if (_hasValue && _id == currentid)
+ base._observer.OnNext(_value);
+ _hasValue = false;
+ }
+
+ return Disposable.Empty;
+ }
+
+ public void OnError(Exception error)
+ {
+ _cancelable.Dispose();
+
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+
+ _hasValue = false;
+ _id = unchecked(_id + 1);
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _cancelable.Dispose();
+
+ lock (_gate)
+ {
+ if (_hasValue)
+ base._observer.OnNext(_value);
+
+ base._observer.OnCompleted();
+ base.Dispose();
+
+ _hasValue = false;
+ _id = unchecked(_id + 1);
+ }
+ }
+ }
+ }
+
+ class Throttle<TSource, TThrottle> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, IObservable<TThrottle>> _throttleSelector;
+
+ public Throttle(IObservable<TSource> source, Func<TSource, IObservable<TThrottle>> throttleSelector)
+ {
+ _source = source;
+ _throttleSelector = throttleSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Throttle<TSource, TThrottle> _parent;
+
+ public _(Throttle<TSource, TThrottle> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private TSource _value;
+ private bool _hasValue;
+ private SerialDisposable _cancelable;
+ private ulong _id;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _value = default(TSource);
+ _hasValue = false;
+ _cancelable = new SerialDisposable();
+ _id = 0UL;
+
+ var subscription = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(subscription, _cancelable);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var throttle = default(IObservable<TThrottle>);
+ try
+ {
+ throttle = _parent._throttleSelector(value);
+ }
+ catch (Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ return;
+ }
+
+ ulong currentid;
+ lock (_gate)
+ {
+ _hasValue = true;
+ _value = value;
+ _id = unchecked(_id + 1);
+ currentid = _id;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ _cancelable.Disposable = d;
+ d.Disposable = throttle.SubscribeSafe(new δ(this, value, currentid, d));
+ }
+
+ public void OnError(Exception error)
+ {
+ _cancelable.Dispose();
+
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+
+ _hasValue = false;
+ _id = unchecked(_id + 1);
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _cancelable.Dispose();
+
+ lock (_gate)
+ {
+ if (_hasValue)
+ base._observer.OnNext(_value);
+
+ base._observer.OnCompleted();
+ base.Dispose();
+
+ _hasValue = false;
+ _id = unchecked(_id + 1);
+ }
+ }
+
+ class δ : IObserver<TThrottle>
+ {
+ private readonly _ _parent;
+ private readonly TSource _value;
+ private readonly ulong _currentid;
+ private readonly IDisposable _self;
+
+ public δ(_ parent, TSource value, ulong currentid, IDisposable self)
+ {
+ _parent = parent;
+ _value = value;
+ _currentid = currentid;
+ _self = self;
+ }
+
+ public void OnNext(TThrottle value)
+ {
+ lock (_parent._gate)
+ {
+ if (_parent._hasValue && _parent._id == _currentid)
+ _parent._observer.OnNext(_value);
+
+ _parent._hasValue = false;
+ _self.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ if (_parent._hasValue && _parent._id == _currentid)
+ _parent._observer.OnNext(_value);
+
+ _parent._hasValue = false;
+ _self.Dispose();
+ }
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Throw.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Throw.cs
new file mode 100644
index 0000000..3b10894
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Throw.cs
@@ -0,0 +1,50 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Throw<TResult> : Producer<TResult>
+ {
+ private readonly Exception _exception;
+ private readonly IScheduler _scheduler;
+
+ public Throw(Exception exception, IScheduler scheduler)
+ {
+ _exception = exception;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TResult>
+ {
+ private readonly Throw<TResult> _parent;
+
+ public _(Throw<TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ return _parent._scheduler.Schedule(Invoke);
+ }
+
+ private void Invoke()
+ {
+ base._observer.OnError(_parent._exception);
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TimeInterval.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TimeInterval.cs
new file mode 100644
index 0000000..dacfa03
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TimeInterval.cs
@@ -0,0 +1,73 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Diagnostics;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class TimeInterval<TSource> : Producer<System.Reactive.TimeInterval<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly IScheduler _scheduler;
+
+ public TimeInterval(IObservable<TSource> source, IScheduler scheduler)
+ {
+ _source = source;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<System.Reactive.TimeInterval<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<System.Reactive.TimeInterval<TSource>>, IObserver<TSource>
+ {
+ private readonly TimeInterval<TSource> _parent;
+
+ public _(TimeInterval<TSource> parent, IObserver<System.Reactive.TimeInterval<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private IStopwatch _watch;
+ private TimeSpan _last;
+
+ public IDisposable Run()
+ {
+ _watch = _parent._scheduler.StartStopwatch();
+ _last = TimeSpan.Zero;
+
+ return _parent._source.Subscribe(this);
+ }
+
+ public void OnNext(TSource value)
+ {
+ var now = _watch.Elapsed;
+ var span = now.Subtract(_last);
+ _last = now;
+ base._observer.OnNext(new System.Reactive.TimeInterval<TSource>(value, span));
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timeout.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timeout.cs
new file mode 100644
index 0000000..4896294
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timeout.cs
@@ -0,0 +1,432 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Timeout<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly TimeSpan? _dueTimeR;
+ private readonly DateTimeOffset? _dueTimeA;
+ private readonly IObservable<TSource> _other;
+ private readonly IScheduler _scheduler;
+
+ public Timeout(IObservable<TSource> source, TimeSpan dueTime, IObservable<TSource> other, IScheduler scheduler)
+ {
+ _source = source;
+ _dueTimeR = dueTime;
+ _other = other;
+ _scheduler = scheduler;
+ }
+
+ public Timeout(IObservable<TSource> source, DateTimeOffset dueTime, IObservable<TSource> other, IScheduler scheduler)
+ {
+ _source = source;
+ _dueTimeA = dueTime;
+ _other = other;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_dueTimeA.HasValue)
+ {
+ var sink = new α(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new ρ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class α : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Timeout<TSource> _parent;
+
+ public α(Timeout<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private SerialDisposable _subscription;
+ private object _gate;
+ private bool _switched;
+
+ public IDisposable Run()
+ {
+ _subscription = new SerialDisposable();
+ var original = new SingleAssignmentDisposable();
+
+ _subscription.Disposable = original;
+
+ _gate = new object();
+ _switched = false;
+
+ var timer = _parent._scheduler.Schedule(_parent._dueTimeA.Value, Timeout);
+
+ original.Disposable = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(_subscription, timer);
+ }
+
+ private void Timeout()
+ {
+ var timerWins = false;
+
+ lock (_gate)
+ {
+ timerWins = !_switched;
+ _switched = true;
+ }
+
+ if (timerWins)
+ _subscription.Disposable = _parent._other.SubscribeSafe(this.GetForwarder());
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ if (!_switched)
+ base._observer.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ var onErrorWins = false;
+
+ lock (_gate)
+ {
+ onErrorWins = !_switched;
+ _switched = true;
+ }
+
+ if (onErrorWins)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ var onCompletedWins = false;
+
+ lock (_gate)
+ {
+ onCompletedWins = !_switched;
+ _switched = true;
+ }
+
+ if (onCompletedWins)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class ρ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Timeout<TSource> _parent;
+
+ public ρ(Timeout<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private SerialDisposable _subscription;
+ private SerialDisposable _timer;
+
+ private object _gate;
+ private ulong _id;
+ private bool _switched;
+
+ public IDisposable Run()
+ {
+ _subscription = new SerialDisposable();
+ _timer = new SerialDisposable();
+ var original = new SingleAssignmentDisposable();
+
+ _subscription.Disposable = original;
+
+ _gate = new object();
+ _id = 0UL;
+ _switched = false;
+
+ CreateTimer();
+
+ original.Disposable = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(_subscription, _timer);
+ }
+
+ private void CreateTimer()
+ {
+ _timer.Disposable = _parent._scheduler.Schedule(_id, _parent._dueTimeR.Value, Timeout);
+ }
+
+ private IDisposable Timeout(IScheduler _, ulong myid)
+ {
+ var timerWins = false;
+
+ lock (_gate)
+ {
+ _switched = (_id == myid);
+ timerWins = _switched;
+ }
+
+ if (timerWins)
+ _subscription.Disposable = _parent._other.SubscribeSafe(this.GetForwarder());
+
+ return Disposable.Empty;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var onNextWins = false;
+
+ lock (_gate)
+ {
+ onNextWins = !_switched;
+ if (onNextWins)
+ {
+ _id = unchecked(_id + 1);
+ }
+ }
+
+ if (onNextWins)
+ {
+ base._observer.OnNext(value);
+ CreateTimer();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ var onErrorWins = false;
+
+ lock (_gate)
+ {
+ onErrorWins = !_switched;
+ if (onErrorWins)
+ {
+ _id = unchecked(_id + 1);
+ }
+ }
+
+ if (onErrorWins)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ var onCompletedWins = false;
+
+ lock (_gate)
+ {
+ onCompletedWins = !_switched;
+ if (onCompletedWins)
+ {
+ _id = unchecked(_id + 1);
+ }
+ }
+
+ if (onCompletedWins)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+
+ class Timeout<TSource, TTimeout> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly IObservable<TTimeout> _firstTimeout;
+ private readonly Func<TSource, IObservable<TTimeout>> _timeoutSelector;
+ private readonly IObservable<TSource> _other;
+
+ public Timeout(IObservable<TSource> source, IObservable<TTimeout> firstTimeout, Func<TSource, IObservable<TTimeout>> timeoutSelector, IObservable<TSource> other)
+ {
+ _source = source;
+ _firstTimeout = firstTimeout;
+ _timeoutSelector = timeoutSelector;
+ _other = other;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Timeout<TSource, TTimeout> _parent;
+
+ public _(Timeout<TSource, TTimeout> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private SerialDisposable _subscription;
+ private SerialDisposable _timer;
+ private object _gate;
+ private ulong _id;
+ private bool _switched;
+
+ public IDisposable Run()
+ {
+ _subscription = new SerialDisposable();
+ _timer = new SerialDisposable();
+ var original = new SingleAssignmentDisposable();
+
+ _subscription.Disposable = original;
+
+ _gate = new object();
+ _id = 0UL;
+ _switched = false;
+
+ SetTimer(_parent._firstTimeout);
+
+ original.Disposable = _parent._source.SubscribeSafe(this);
+
+ return new CompositeDisposable(_subscription, _timer);
+ }
+
+ public void OnNext(TSource value)
+ {
+ if (ObserverWins())
+ {
+ base._observer.OnNext(value);
+
+ var timeout = default(IObservable<TTimeout>);
+ try
+ {
+ timeout = _parent._timeoutSelector(value);
+ }
+ catch (Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ return;
+ }
+
+ SetTimer(timeout);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ if (ObserverWins())
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ if (ObserverWins())
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ private void SetTimer(IObservable<TTimeout> timeout)
+ {
+ var myid = _id;
+
+ var d = new SingleAssignmentDisposable();
+ _timer.Disposable = d;
+ d.Disposable = timeout.SubscribeSafe(new τ(this, myid, d));
+ }
+
+ class τ : IObserver<TTimeout>
+ {
+ private readonly _ _parent;
+ private readonly ulong _id;
+ private readonly IDisposable _self;
+
+ public τ(_ parent, ulong id, IDisposable self)
+ {
+ _parent = parent;
+ _id = id;
+ _self = self;
+ }
+
+ public void OnNext(TTimeout value)
+ {
+ if (TimerWins())
+ _parent._subscription.Disposable = _parent._parent._other.SubscribeSafe(_parent.GetForwarder());
+
+ _self.Dispose();
+ }
+
+ public void OnError(Exception error)
+ {
+ if (TimerWins())
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ if (TimerWins())
+ _parent._subscription.Disposable = _parent._parent._other.SubscribeSafe(_parent.GetForwarder());
+ }
+
+ private bool TimerWins()
+ {
+ var res = false;
+
+ lock (_parent._gate)
+ {
+ _parent._switched = (_parent._id == _id);
+ res = _parent._switched;
+ }
+
+ return res;
+ }
+ }
+
+ private bool ObserverWins()
+ {
+ var res = false;
+
+ lock (_gate)
+ {
+ res = !_switched;
+ if (res)
+ {
+ _id = unchecked(_id + 1);
+ }
+ }
+
+ return res;
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timer.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timer.cs
new file mode 100644
index 0000000..22ee0df
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timer.cs
@@ -0,0 +1,264 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Diagnostics;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Timer : Producer<long>
+ {
+ private readonly DateTimeOffset? _dueTimeA;
+ private readonly TimeSpan? _dueTimeR;
+ private readonly TimeSpan? _period;
+ private readonly IScheduler _scheduler;
+
+ public Timer(DateTimeOffset dueTime, TimeSpan? period, IScheduler scheduler)
+ {
+ _dueTimeA = dueTime;
+ _period = period;
+ _scheduler = scheduler;
+ }
+
+ public Timer(TimeSpan dueTime, TimeSpan? period, IScheduler scheduler)
+ {
+ _dueTimeR = dueTime;
+ _period = period;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_period.HasValue)
+ {
+ var sink = new π(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<long>
+ {
+ private readonly Timer _parent;
+
+ public _(Timer parent, IObserver<long> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ if (_parent._dueTimeA.HasValue)
+ {
+ return _parent._scheduler.Schedule(_parent._dueTimeA.Value, Invoke);
+ }
+ else
+ {
+ return _parent._scheduler.Schedule(_parent._dueTimeR.Value, Invoke);
+ }
+ }
+
+ private void Invoke()
+ {
+ base._observer.OnNext(0);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class π : Sink<long>
+ {
+ private readonly Timer _parent;
+ private readonly TimeSpan _period;
+
+ public π(Timer parent, IObserver<long> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _period = _parent._period.Value;
+ }
+
+ public IDisposable Run()
+ {
+ if (_parent._dueTimeA.HasValue)
+ {
+ var dueTime = _parent._dueTimeA.Value;
+ return _parent._scheduler.Schedule(default(object), dueTime, InvokeStart);
+ }
+ else
+ {
+ var dueTime = _parent._dueTimeR.Value;
+
+ //
+ // Optimize for the case of Observable.Interval.
+ //
+ if (dueTime == _period)
+ {
+ return _parent._scheduler.SchedulePeriodic(0L, _period, (Func<long, long>)Tick);
+ }
+
+ return _parent._scheduler.Schedule(default(object), dueTime, InvokeStart);
+ }
+ }
+
+ //
+ // BREAKING CHANGE v2 > v1.x - No more correction for time drift based on absolute time. This
+ // didn't work for large period values anyway; the fractional
+ // error exceeded corrections. Also complicated dealing with system
+ // clock change conditions and caused numerous bugs.
+ //
+ // - For more precise scheduling, use a custom scheduler that measures TimeSpan values in a
+ // better way, e.g. spinning to make up for the last part of the period. Whether or not the
+ // values of the TimeSpan period match NT time or wall clock time is up to the scheduler.
+ //
+ // - For more accurate scheduling wrt the system clock, use Generate with DateTimeOffset time
+ // selectors. When the system clock changes, intervals will not be the same as diffs between
+ // consecutive absolute time values. The precision will be low (1s range by default).
+ //
+ private long Tick(long count)
+ {
+ base._observer.OnNext(count);
+ return unchecked(count + 1);
+ }
+
+ private int _pendingTickCount;
+ private IDisposable _periodic;
+
+ private IDisposable InvokeStart(IScheduler self, object state)
+ {
+ //
+ // Notice the first call to OnNext will introduce skew if it takes significantly long when
+ // using the following naive implementation:
+ //
+ // Code: base._observer.OnNext(0L);
+ // return self.SchedulePeriodicEmulated(1L, _period, (Func<long, long>)Tick);
+ //
+ // What we're saying here is that Observable.Timer(dueTime, period) is pretty much the same
+ // as writing Observable.Timer(dueTime).Concat(Observable.Interval(period)).
+ //
+ // Expected: dueTime
+ // |
+ // 0--period--1--period--2--period--3--period--4--...
+ // |
+ // +-OnNext(0L)-|
+ //
+ // Actual: dueTime
+ // |
+ // 0------------#--period--1--period--2--period--3--period--4--...
+ // |
+ // +-OnNext(0L)-|
+ //
+ // Different solutions for this behavior have different problems:
+ //
+ // 1. Scheduling the periodic job first and using an AsyncLock to serialize the OnNext calls
+ // has the drawback that InvokeStart may never return. This happens when every callback
+ // doesn't meet the period's deadline, hence the periodic job keeps queueing stuff up. In
+ // this case, InvokeStart stays the owner of the AsyncLock and the call to Wait will never
+ // return, thus not allowing any interleaving of work on this scheduler's logical thread.
+ //
+ // 2. Scheduling the periodic job first and using a (blocking) synchronization primitive to
+ // signal completion of the OnNext(0L) call to the Tick call requires quite a bit of state
+ // and careful handling of the case when OnNext(0L) throws. What's worse is the blocking
+ // behavior inside Tick.
+ //
+ // In order to avoid blocking behavior, we need a scheme much like SchedulePeriodic emulation
+ // where work to dispatch OnNext(n + 1) is delegated to a catch up loop in case OnNext(n) was
+ // still running. Because SchedulePeriodic emulation exhibits such behavior in all cases, we
+ // only need to deal with the overlap of OnNext(0L) with future periodic OnNext(n) dispatch
+ // jobs. In the worst case where every callback takes longer than the deadline implied by the
+ // period, the periodic job will just queue up work that's dispatched by the tail-recursive
+ // catch up loop. In the best case, all work will be dispatched on the periodic scheduler.
+ //
+
+ //
+ // We start with one tick pending because we're about to start doing OnNext(0L).
+ //
+ _pendingTickCount = 1;
+
+ var d = new SingleAssignmentDisposable();
+ _periodic = d;
+ d.Disposable = self.SchedulePeriodic(1L, _period, (Func<long, long>)Tock);
+
+ try
+ {
+ base._observer.OnNext(0L);
+ }
+ catch (Exception e)
+ {
+ d.Dispose();
+ e.Throw();
+ }
+
+ //
+ // If the periodic scheduling job already ran before we finished dispatching the OnNext(0L)
+ // call, we'll find pendingTickCount to be > 1. In this case, we need to catch up by dispatching
+ // subsequent calls to OnNext as fast as possible, but without running a loop in order to ensure
+ // fair play with the scheduler. So, we run a tail-recursive loop in CatchUp instead.
+ //
+ if (Interlocked.Decrement(ref _pendingTickCount) > 0)
+ {
+ var c = new SingleAssignmentDisposable();
+ c.Disposable = self.Schedule(1L, CatchUp);
+
+ return new CompositeDisposable(2) { d, c };
+ }
+
+ return d;
+ }
+
+ private long Tock(long count)
+ {
+ //
+ // Notice the handler for (emulated) periodic scheduling is non-reentrant.
+ //
+ // When there's no overlap with the OnNext(0L) call, the following code will cycle through
+ // pendingTickCount 0 -> 1 -> 0 for the remainder of the timer's execution.
+ //
+ // If there's overlap with the OnNext(0L) call, pendingTickCount will increase to record
+ // the number of catch up OnNext calls required, which will be dispatched by the recursive
+ // scheduling loop in CatchUp (which quits when it reaches 0 pending ticks).
+ //
+ if (Interlocked.Increment(ref _pendingTickCount) == 1)
+ {
+ base._observer.OnNext(count);
+ Interlocked.Decrement(ref _pendingTickCount);
+ }
+
+ return unchecked(count + 1);
+ }
+
+ private void CatchUp(long count, Action<long> recurse)
+ {
+ try
+ {
+ base._observer.OnNext(count);
+ }
+ catch (Exception e)
+ {
+ _periodic.Dispose();
+ e.Throw();
+ }
+
+ //
+ // We can simply bail out if we decreased the tick count to 0. In that case, the Tock
+ // method will take over when it sees the 0 -> 1 transition.
+ //
+ if (Interlocked.Decrement(ref _pendingTickCount) > 0)
+ {
+ recurse(unchecked(count + 1));
+ }
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timestamp.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timestamp.cs
new file mode 100644
index 0000000..ed54678
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timestamp.cs
@@ -0,0 +1,56 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Concurrency;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Timestamp<TSource> : Producer<Timestamped<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly IScheduler _scheduler;
+
+ public Timestamp(IObservable<TSource> source, IScheduler scheduler)
+ {
+ _source = source;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<Timestamped<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<Timestamped<TSource>>, IObserver<TSource>
+ {
+ private readonly Timestamp<TSource> _parent;
+
+ public _(Timestamp<TSource> parent, IObserver<Timestamped<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(new Timestamped<TSource>(value, _parent._scheduler.Now));
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToArray.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToArray.cs
new file mode 100644
index 0000000..ba039ae
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToArray.cs
@@ -0,0 +1,55 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class ToArray<TSource> : Producer<TSource[]>
+ {
+ private readonly IObservable<TSource> _source;
+
+ public ToArray(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<TSource[]> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<TSource[]>, IObserver<TSource>
+ {
+ private List<TSource> _list;
+
+ public _(IObserver<TSource[]> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _list = new List<TSource>();
+ }
+
+ public void OnNext(TSource value)
+ {
+ _list.Add(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_list.ToArray());
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToDictionary.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToDictionary.cs
new file mode 100644
index 0000000..919c1a1
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToDictionary.cs
@@ -0,0 +1,71 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class ToDictionary<TSource, TKey, TElement> : Producer<IDictionary<TKey, TElement>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TKey> _keySelector;
+ private readonly Func<TSource, TElement> _elementSelector;
+ private readonly IEqualityComparer<TKey> _comparer;
+
+ public ToDictionary(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+ {
+ _source = source;
+ _keySelector = keySelector;
+ _elementSelector = elementSelector;
+ _comparer = comparer;
+ }
+
+ protected override IDisposable Run(IObserver<IDictionary<TKey, TElement>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<IDictionary<TKey, TElement>>, IObserver<TSource>
+ {
+ private readonly ToDictionary<TSource, TKey, TElement> _parent;
+ private Dictionary<TKey, TElement> _dictionary;
+
+ public _(ToDictionary<TSource, TKey, TElement> parent, IObserver<IDictionary<TKey, TElement>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _dictionary = new Dictionary<TKey, TElement>(_parent._comparer);
+ }
+
+ public void OnNext(TSource value)
+ {
+ try
+ {
+ _dictionary.Add(_parent._keySelector(value), _parent._elementSelector(value));
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_dictionary);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToList.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToList.cs
new file mode 100644
index 0000000..34956d4
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToList.cs
@@ -0,0 +1,55 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class ToList<TSource> : Producer<IList<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+
+ public ToList(IObservable<TSource> source)
+ {
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<IList<TSource>>, IObserver<TSource>
+ {
+ private List<TSource> _list;
+
+ public _(IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _list = new List<TSource>();
+ }
+
+ public void OnNext(TSource value)
+ {
+ _list.Add(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_list);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToLookup.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToLookup.cs
new file mode 100644
index 0000000..55ff7d3
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToLookup.cs
@@ -0,0 +1,72 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class ToLookup<TSource, TKey, TElement> : Producer<ILookup<TKey, TElement>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TKey> _keySelector;
+ private readonly Func<TSource, TElement> _elementSelector;
+ private readonly IEqualityComparer<TKey> _comparer;
+
+ public ToLookup(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+ {
+ _source = source;
+ _keySelector = keySelector;
+ _elementSelector = elementSelector;
+ _comparer = comparer;
+ }
+
+ protected override IDisposable Run(IObserver<ILookup<TKey, TElement>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+
+ class _ : Sink<ILookup<TKey, TElement>>, IObserver<TSource>
+ {
+ private readonly ToLookup<TSource, TKey, TElement> _parent;
+ private Lookup<TKey, TElement> _lookup;
+
+ public _(ToLookup<TSource, TKey, TElement> parent, IObserver<ILookup<TKey, TElement>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _lookup = new Lookup<TKey, TElement>(_parent._comparer);
+ }
+
+ public void OnNext(TSource value)
+ {
+ try
+ {
+ _lookup.Add(_parent._keySelector(value), _parent._elementSelector(value));
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnNext(_lookup);
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToObservable.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToObservable.cs
new file mode 100644
index 0000000..795d54d
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToObservable.cs
@@ -0,0 +1,174 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class ToObservable<TSource> : Producer<TSource>
+ {
+ private readonly IEnumerable<TSource> _source;
+ private readonly IScheduler _scheduler;
+
+ public ToObservable(IEnumerable<TSource> source, IScheduler scheduler)
+ {
+ _source = source;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>
+ {
+ private readonly ToObservable<TSource> _parent;
+
+ public _(ToObservable<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var e = default(IEnumerator<TSource>);
+ try
+ {
+ e = _parent._source.GetEnumerator();
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ var longRunning = _parent._scheduler.AsLongRunning();
+ if (longRunning != null)
+ {
+ //
+ // Long-running schedulers have the contract they should *never* prevent
+ // the work from starting, such that the scheduled work has the chance
+ // to observe the cancellation and perform proper clean-up. In this case,
+ // we're sure Loop will be entered, allowing us to dispose the enumerator.
+ //
+ return longRunning.ScheduleLongRunning(e, Loop);
+ }
+ else
+ {
+ //
+ // We never allow the scheduled work to be cancelled. Instead, the flag
+ // is used to have LoopRec bail out and perform proper clean-up of the
+ // enumerator.
+ //
+ var flag = new BooleanDisposable();
+ _parent._scheduler.Schedule(new State(flag, e), LoopRec);
+ return flag;
+ }
+ }
+
+ class State
+ {
+ public readonly ICancelable flag;
+ public readonly IEnumerator<TSource> enumerator;
+
+ public State(ICancelable flag, IEnumerator<TSource> enumerator)
+ {
+ this.flag = flag;
+ this.enumerator = enumerator;
+ }
+ }
+
+ private void LoopRec(State state, Action<State> recurse)
+ {
+ var hasNext = false;
+ var ex = default(Exception);
+ var current = default(TSource);
+
+ if (state.flag.IsDisposed)
+ {
+ state.enumerator.Dispose();
+ return;
+ }
+
+ try
+ {
+ hasNext = state.enumerator.MoveNext();
+ if (hasNext)
+ current = state.enumerator.Current;
+ }
+ catch (Exception exception)
+ {
+ ex = exception;
+ }
+
+ if (ex != null)
+ {
+ state.enumerator.Dispose();
+
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (!hasNext)
+ {
+ state.enumerator.Dispose();
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(current);
+ recurse(state);
+ }
+
+ private void Loop(IEnumerator<TSource> enumerator, ICancelable cancel)
+ {
+ while (!cancel.IsDisposed)
+ {
+ var hasNext = false;
+ var ex = default(Exception);
+ var current = default(TSource);
+
+ try
+ {
+ hasNext = enumerator.MoveNext();
+ if (hasNext)
+ current = enumerator.Current;
+ }
+ catch (Exception exception)
+ {
+ ex = exception;
+ }
+
+ if (ex != null)
+ {
+ base._observer.OnError(ex);
+ break;
+ }
+
+ if (!hasNext)
+ {
+ base._observer.OnCompleted();
+ break;
+ }
+
+ base._observer.OnNext(current);
+ }
+
+ enumerator.Dispose();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Using.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Using.cs
new file mode 100644
index 0000000..996ee0e
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Using.cs
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Using<TSource, TResource> : Producer<TSource>
+ where TResource : IDisposable
+ {
+ private readonly Func<TResource> _resourceFactory;
+ private readonly Func<TResource, IObservable<TSource>> _observableFactory;
+
+ public Using(Func<TResource> resourceFactory, Func<TResource, IObservable<TSource>> observableFactory)
+ {
+ _resourceFactory = resourceFactory;
+ _observableFactory = observableFactory;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Using<TSource, TResource> _parent;
+
+ public _(Using<TSource, TResource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public IDisposable Run()
+ {
+ var source = default(IObservable<TSource>);
+ var disposable = Disposable.Empty;
+ try
+ {
+ var resource = _parent._resourceFactory();
+ if (resource != null)
+ disposable = resource;
+ source = _parent._observableFactory(resource);
+ }
+ catch (Exception exception)
+ {
+ return new CompositeDisposable(Observable.Throw<TSource>(exception).SubscribeSafe(this), disposable);
+ }
+
+ return new CompositeDisposable(source.SubscribeSafe(this), disposable);
+ }
+
+ public void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Where.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Where.cs
new file mode 100644
index 0000000..a8eaa92
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Where.cs
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Where<TSource> : Producer<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+ private readonly Func<TSource, int, bool> _predicateI;
+
+ public Where(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ _source = source;
+ _predicate = predicate;
+ }
+
+ public Where(IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+ _source = source;
+ _predicateI = predicate;
+ }
+
+ public IObservable<TSource> Ω(Func<TSource, bool> predicate)
+ {
+ if (_predicate != null)
+ return new Where<TSource>(_source, x => _predicate(x) && predicate(x));
+ else
+ return new Where<TSource>(this, predicate);
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_predicate != null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return _source.SubscribeSafe(sink);
+ }
+ }
+
+ class _ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Where<TSource> _parent;
+
+ public _(Where<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var shouldRun = default(bool);
+ try
+ {
+ shouldRun = _parent._predicate(value);
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ if (shouldRun)
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<TSource>, IObserver<TSource>
+ {
+ private readonly Where<TSource> _parent;
+ private int _index;
+
+ public τ(Where<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ _index = 0;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var shouldRun = default(bool);
+ try
+ {
+ shouldRun = _parent._predicateI(value, checked(_index++));
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return;
+ }
+
+ if (shouldRun)
+ base._observer.OnNext(value);
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/While.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/While.cs
new file mode 100644
index 0000000..178e4c8
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/While.cs
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class While<TSource> : Producer<TSource>, IConcatenatable<TSource>
+ {
+ private readonly Func<bool> _condition;
+ private readonly IObservable<TSource> _source;
+
+ public While(Func<bool> condition, IObservable<TSource> source)
+ {
+ _condition = condition;
+ _source = source;
+ }
+
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(observer, cancel);
+ setSink(sink);
+ return sink.Run(GetSources());
+ }
+
+ public IEnumerable<IObservable<TSource>> GetSources()
+ {
+ while (_condition())
+ yield return _source;
+ }
+
+ class _ : ConcatSink<TSource>
+ {
+ public _(IObserver<TSource> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ }
+
+ public override void OnNext(TSource value)
+ {
+ base._observer.OnNext(value);
+ }
+
+ public override void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+ }
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Window.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Window.cs
new file mode 100644
index 0000000..47059c7
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Window.cs
@@ -0,0 +1,758 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+using System.Threading;
+
+namespace System.Reactive.Linq.Observαble
+{
+ class Window<TSource> : Producer<IObservable<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly int _count;
+ private readonly int _skip;
+
+ private readonly TimeSpan _timeSpan;
+ private readonly TimeSpan _timeShift;
+ private readonly IScheduler _scheduler;
+
+ public Window(IObservable<TSource> source, int count, int skip)
+ {
+ _source = source;
+ _count = count;
+ _skip = skip;
+ }
+
+ public Window(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler)
+ {
+ _source = source;
+ _timeSpan = timeSpan;
+ _timeShift = timeShift;
+ _scheduler = scheduler;
+ }
+
+ public Window(IObservable<TSource> source, TimeSpan timeSpan, int count, IScheduler scheduler)
+ {
+ _source = source;
+ _timeSpan = timeSpan;
+ _count = count;
+ _scheduler = scheduler;
+ }
+
+ protected override IDisposable Run(IObserver<IObservable<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_scheduler == null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else if (_count > 0)
+ {
+ var sink = new μ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ if (_timeSpan == _timeShift)
+ {
+ var sink = new π(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new τ(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+ }
+
+ class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+ {
+ private readonly Window<TSource> _parent;
+
+ public _(Window<TSource> parent, IObserver<IObservable<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private Queue<ISubject<TSource>> _queue;
+ private int _n;
+ private SingleAssignmentDisposable _m;
+ private RefCountDisposable _refCountDisposable;
+
+ public IDisposable Run()
+ {
+ _queue = new Queue<ISubject<TSource>>();
+ _n = 0;
+ _m = new SingleAssignmentDisposable();
+ _refCountDisposable = new RefCountDisposable(_m);
+
+ var firstWindow = CreateWindow();
+ base._observer.OnNext(firstWindow);
+
+ _m.Disposable = _parent._source.SubscribeSafe(this);
+
+ return _refCountDisposable;
+ }
+
+ private IObservable<TSource> CreateWindow()
+ {
+ var s = new Subject<TSource>();
+ _queue.Enqueue(s);
+ return new WindowObservable<TSource>(s, _refCountDisposable);
+ }
+
+ public void OnNext(TSource value)
+ {
+ foreach (var s in _queue)
+ s.OnNext(value);
+
+ var c = _n - _parent._count + 1;
+ if (c >= 0 && c % _parent._skip == 0)
+ {
+ var s = _queue.Dequeue();
+ s.OnCompleted();
+ }
+
+ _n++;
+ if (_n % _parent._skip == 0)
+ {
+ var newWindow = CreateWindow();
+ base._observer.OnNext(newWindow);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ while (_queue.Count > 0)
+ _queue.Dequeue().OnError(error);
+
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ while (_queue.Count > 0)
+ _queue.Dequeue().OnCompleted();
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ class τ : Sink<IObservable<TSource>>, IObserver<TSource>
+ {
+ private readonly Window<TSource> _parent;
+
+ public τ(Window<TSource> parent, IObserver<IObservable<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private TimeSpan _totalTime;
+ private TimeSpan _nextShift;
+ private TimeSpan _nextSpan;
+
+ private object _gate;
+ private Queue<ISubject<TSource>> _q;
+
+ private SerialDisposable _timerD;
+ private RefCountDisposable _refCountDisposable;
+
+ public IDisposable Run()
+ {
+ _totalTime = TimeSpan.Zero;
+ _nextShift = _parent._timeShift;
+ _nextSpan = _parent._timeSpan;
+
+ _gate = new object();
+ _q = new Queue<ISubject<TSource>>();
+
+ _timerD = new SerialDisposable();
+
+ var groupDisposable = new CompositeDisposable(2) { _timerD };
+ _refCountDisposable = new RefCountDisposable(groupDisposable);
+
+ CreateWindow();
+ CreateTimer();
+
+ groupDisposable.Add(_parent._source.SubscribeSafe(this));
+
+ return _refCountDisposable;
+ }
+
+ private void CreateWindow()
+ {
+ var s = new Subject<TSource>();
+ _q.Enqueue(s);
+ base._observer.OnNext(new WindowObservable<TSource>(s, _refCountDisposable));
+ }
+
+ private void CreateTimer()
+ {
+ var m = new SingleAssignmentDisposable();
+ _timerD.Disposable = m;
+
+ var isSpan = false;
+ var isShift = false;
+ if (_nextSpan == _nextShift)
+ {
+ isSpan = true;
+ isShift = true;
+ }
+ else if (_nextSpan < _nextShift)
+ isSpan = true;
+ else
+ isShift = true;
+
+ var newTotalTime = isSpan ? _nextSpan : _nextShift;
+ var ts = newTotalTime - _totalTime;
+ _totalTime = newTotalTime;
+
+ if (isSpan)
+ _nextSpan += _parent._timeShift;
+ if (isShift)
+ _nextShift += _parent._timeShift;
+
+ m.Disposable = _parent._scheduler.Schedule(new State { isSpan = isSpan, isShift = isShift }, ts, Tick);
+ }
+
+ struct State
+ {
+ public bool isSpan;
+ public bool isShift;
+ }
+
+ private IDisposable Tick(IScheduler self, State state)
+ {
+ lock (_gate)
+ {
+ //
+ // BREAKING CHANGE v2 > v1.x - Making behavior of sending OnCompleted to the window
+ // before sending out a new window consistent across all
+ // overloads of Window and Buffer. Before v2, the two
+ // operations below were reversed.
+ //
+ if (state.isSpan)
+ {
+ var s = _q.Dequeue();
+ s.OnCompleted();
+ }
+
+ if (state.isShift)
+ {
+ CreateWindow();
+ }
+ }
+
+ CreateTimer();
+
+ return Disposable.Empty;
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ foreach (var s in _q)
+ s.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ foreach (var s in _q)
+ s.OnError(error);
+
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ foreach (var s in _q)
+ s.OnCompleted();
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class π : Sink<IObservable<TSource>>, IObserver<TSource>
+ {
+ private readonly Window<TSource> _parent;
+
+ public π(Window<TSource> parent, IObserver<IObservable<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private Subject<TSource> _subject;
+ private RefCountDisposable _refCountDisposable;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+
+ var groupDisposable = new CompositeDisposable(2);
+ _refCountDisposable = new RefCountDisposable(groupDisposable);
+
+ CreateWindow();
+
+ groupDisposable.Add(_parent._scheduler.SchedulePeriodic(_parent._timeSpan, Tick));
+ groupDisposable.Add(_parent._source.SubscribeSafe(this));
+
+ return _refCountDisposable;
+ }
+
+ private void Tick()
+ {
+ lock (_gate)
+ {
+ _subject.OnCompleted();
+ CreateWindow();
+ }
+ }
+
+ private void CreateWindow()
+ {
+ _subject = new Subject<TSource>();
+ base._observer.OnNext(new WindowObservable<TSource>(_subject, _refCountDisposable));
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ _subject.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ _subject.OnError(error);
+
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ _subject.OnCompleted();
+
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class μ : Sink<IObservable<TSource>>, IObserver<TSource>
+ {
+ private readonly Window<TSource> _parent;
+
+ public μ(Window<TSource> parent, IObserver<IObservable<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private ISubject<TSource> _s;
+ private int _n;
+ private int _windowId;
+
+ private SerialDisposable _timerD;
+ private RefCountDisposable _refCountDisposable;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+ _s = default(ISubject<TSource>);
+ _n = 0;
+ _windowId = 0;
+
+ _timerD = new SerialDisposable();
+ var groupDisposable = new CompositeDisposable(2) { _timerD };
+ _refCountDisposable = new RefCountDisposable(groupDisposable);
+
+ _s = new Subject<TSource>();
+ base._observer.OnNext(new WindowObservable<TSource>(_s, _refCountDisposable));
+ CreateTimer(0);
+
+ groupDisposable.Add(_parent._source.SubscribeSafe(this));
+
+ return _refCountDisposable;
+ }
+
+ private void CreateTimer(int id)
+ {
+ var m = new SingleAssignmentDisposable();
+ _timerD.Disposable = m;
+
+ m.Disposable = _parent._scheduler.Schedule(id, _parent._timeSpan, Tick);
+ }
+
+ private IDisposable Tick(IScheduler self, int id)
+ {
+ var d = Disposable.Empty;
+
+ var newId = 0;
+ lock (_gate)
+ {
+ if (id != _windowId)
+ return d;
+
+ _n = 0;
+ newId = ++_windowId;
+
+ _s.OnCompleted();
+ _s = new Subject<TSource>();
+ base._observer.OnNext(new WindowObservable<TSource>(_s, _refCountDisposable));
+ }
+
+ CreateTimer(newId);
+
+ return d;
+ }
+
+ public void OnNext(TSource value)
+ {
+ var newWindow = false;
+ var newId = 0;
+
+ lock (_gate)
+ {
+ _s.OnNext(value);
+
+ _n++;
+ if (_n == _parent._count)
+ {
+ newWindow = true;
+ _n = 0;
+ newId = ++_windowId;
+
+ _s.OnCompleted();
+ _s = new Subject<TSource>();
+ base._observer.OnNext(new WindowObservable<TSource>(_s, _refCountDisposable));
+ }
+ }
+
+ if (newWindow)
+ CreateTimer(newId);
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ _s.OnError(error);
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ _s.OnCompleted();
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+
+ class Window<TSource, TWindowClosing> : Producer<IObservable<TSource>>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<IObservable<TWindowClosing>> _windowClosingSelector;
+ private readonly IObservable<TWindowClosing> _windowBoundaries;
+
+ public Window(IObservable<TSource> source, Func<IObservable<TWindowClosing>> windowClosingSelector)
+ {
+ _source = source;
+ _windowClosingSelector = windowClosingSelector;
+ }
+
+ public Window(IObservable<TSource> source, IObservable<TWindowClosing> windowBoundaries)
+ {
+ _source = source;
+ _windowBoundaries = windowBoundaries;
+ }
+
+ protected override IDisposable Run(IObserver<IObservable<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_windowClosingSelector != null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new β(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+ {
+ private readonly Window<TSource, TWindowClosing> _parent;
+
+ public _(Window<TSource, TWindowClosing> parent, IObserver<IObservable<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ISubject<TSource> _window;
+ private object _gate;
+ private AsyncLock _windowGate;
+
+ private SerialDisposable _m;
+ private RefCountDisposable _refCountDisposable;
+
+ public IDisposable Run()
+ {
+ _window = new Subject<TSource>();
+ _gate = new object();
+ _windowGate = new AsyncLock();
+
+ _m = new SerialDisposable();
+ var groupDisposable = new CompositeDisposable(2) { _m };
+ _refCountDisposable = new RefCountDisposable(groupDisposable);
+
+ var window = new WindowObservable<TSource>(_window, _refCountDisposable);
+ base._observer.OnNext(window);
+
+ groupDisposable.Add(_parent._source.SubscribeSafe(this));
+
+ _windowGate.Wait(CreateWindowClose);
+
+ return _refCountDisposable;
+ }
+
+ private void CreateWindowClose()
+ {
+ var windowClose = default(IObservable<TWindowClosing>);
+ try
+ {
+ windowClose = _parent._windowClosingSelector();
+ }
+ catch (Exception exception)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ }
+ return;
+ }
+
+ var closingSubscription = new SingleAssignmentDisposable();
+ _m.Disposable = closingSubscription;
+ closingSubscription.Disposable = windowClose.SubscribeSafe(new ω(this, closingSubscription));
+ }
+
+ private void CloseWindow(IDisposable closingSubscription)
+ {
+ closingSubscription.Dispose();
+
+ lock (_gate)
+ {
+ _window.OnCompleted();
+ _window = new Subject<TSource>();
+
+ var window = new WindowObservable<TSource>(_window, _refCountDisposable);
+ base._observer.OnNext(window);
+ }
+
+ _windowGate.Wait(CreateWindowClose);
+ }
+
+ class ω : IObserver<TWindowClosing>
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+
+ public ω(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ }
+
+ public void OnNext(TWindowClosing value)
+ {
+ _parent.CloseWindow(_self);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.OnError(error);
+ }
+
+ public void OnCompleted()
+ {
+ _parent.CloseWindow(_self);
+ }
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ _window.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ _window.OnError(error);
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ _window.OnCompleted();
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ class β : Sink<IObservable<TSource>>, IObserver<TSource>
+ {
+ private readonly Window<TSource, TWindowClosing> _parent;
+
+ public β(Window<TSource, TWindowClosing> parent, IObserver<IObservable<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ISubject<TSource> _window;
+ private object _gate;
+
+ private RefCountDisposable _refCountDisposable;
+
+ public IDisposable Run()
+ {
+ _window = new Subject<TSource>();
+ _gate = new object();
+
+ var d = new CompositeDisposable(2);
+ _refCountDisposable = new RefCountDisposable(d);
+
+ var window = new WindowObservable<TSource>(_window, _refCountDisposable);
+ base._observer.OnNext(window);
+
+ d.Add(_parent._source.SubscribeSafe(this));
+ d.Add(_parent._windowBoundaries.SubscribeSafe(new ω(this)));
+
+ return _refCountDisposable;
+ }
+
+ class ω : IObserver<TWindowClosing>
+ {
+ private readonly β _parent;
+
+ public ω(β parent)
+ {
+ _parent = parent;
+ }
+
+ public void OnNext(TWindowClosing value)
+ {
+ lock (_parent._gate)
+ {
+ _parent._window.OnCompleted();
+ _parent._window = new Subject<TSource>();
+
+ var window = new WindowObservable<TSource>(_parent._window, _parent._refCountDisposable);
+ _parent._observer.OnNext(window);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.OnError(error);
+ }
+
+ public void OnCompleted()
+ {
+ _parent.OnCompleted();
+ }
+ }
+
+ public void OnNext(TSource value)
+ {
+ lock (_gate)
+ {
+ _window.OnNext(value);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ _window.OnError(error);
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_gate)
+ {
+ _window.OnCompleted();
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+ }
+
+ class WindowObservable<TSource> : AddRef<TSource>
+ {
+ public WindowObservable(IObservable<TSource> source, RefCountDisposable refCount)
+ : base(source, refCount)
+ {
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Zip.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Zip.cs
new file mode 100644
index 0000000..bde6e29
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Zip.cs
@@ -0,0 +1,2326 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq.Observαble
+{
+ #region Binary
+
+ class Zip<TFirst, TSecond, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<TFirst> _first;
+ private readonly IObservable<TSecond> _second;
+ private readonly IEnumerable<TSecond> _secondE;
+ private readonly Func<TFirst, TSecond, TResult> _resultSelector;
+
+ public Zip(IObservable<TFirst> first, IObservable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
+ {
+ _first = first;
+ _second = second;
+ _resultSelector = resultSelector;
+ }
+
+ public Zip(IObservable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
+ {
+ _first = first;
+ _secondE = second;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ if (_second != null)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ else
+ {
+ var sink = new ε(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+ }
+
+ class _ : Sink<TResult>
+ {
+ private readonly Zip<TFirst, TSecond, TResult> _parent;
+
+ public _(Zip<TFirst, TSecond, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+
+ public IDisposable Run()
+ {
+ _gate = new object();
+
+ var fstSubscription = new SingleAssignmentDisposable();
+ var sndSubscription = new SingleAssignmentDisposable();
+
+ var fstO = new F(this, fstSubscription);
+ var sndO = new S(this, sndSubscription);
+
+ fstO.Other = sndO;
+ sndO.Other = fstO;
+
+ fstSubscription.Disposable = _parent._first.SubscribeSafe(fstO);
+ sndSubscription.Disposable = _parent._second.SubscribeSafe(sndO);
+
+ return new CompositeDisposable(fstSubscription, sndSubscription, fstO, sndO);
+ }
+
+ class F : IObserver<TFirst>, IDisposable
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+ private S _other;
+ private Queue<TFirst> _queue;
+
+ public F(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ _queue = new Queue<TFirst>();
+ }
+
+ public S Other { set { _other = value; } }
+
+ public Queue<TFirst> Queue { get { return _queue; } }
+ public bool Done { get; private set; }
+
+ public void OnNext(TFirst value)
+ {
+ lock (_parent._gate)
+ {
+ if (_other.Queue.Count > 0)
+ {
+ var r = _other.Queue.Dequeue();
+
+ var res = default(TResult);
+ try
+ {
+ res = _parent._parent._resultSelector(value, r);
+ }
+ catch (Exception ex)
+ {
+ _parent._observer.OnError(ex);
+ _parent.Dispose();
+ return;
+ }
+
+ _parent._observer.OnNext(res);
+ }
+ else
+ {
+ if (_other.Done)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ return;
+ }
+
+ _queue.Enqueue(value);
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ Done = true;
+
+ if (_other.Done)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ return;
+ }
+ else
+ {
+ _self.Dispose();
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ _queue.Clear();
+ }
+ }
+
+ class S : IObserver<TSecond>, IDisposable
+ {
+ private readonly _ _parent;
+ private readonly IDisposable _self;
+ private F _other;
+ private Queue<TSecond> _queue;
+
+ public S(_ parent, IDisposable self)
+ {
+ _parent = parent;
+ _self = self;
+ _queue = new Queue<TSecond>();
+ }
+
+ public F Other { set { _other = value; } }
+
+ public Queue<TSecond> Queue { get { return _queue; } }
+ public bool Done { get; private set; }
+
+ public void OnNext(TSecond value)
+ {
+ lock (_parent._gate)
+ {
+ if (_other.Queue.Count > 0)
+ {
+ var l = _other.Queue.Dequeue();
+
+ var res = default(TResult);
+ try
+ {
+ res = _parent._parent._resultSelector(l, value);
+ }
+ catch (Exception ex)
+ {
+ _parent._observer.OnError(ex);
+ _parent.Dispose();
+ return;
+ }
+
+ _parent._observer.OnNext(res);
+ }
+ else
+ {
+ if (_other.Done)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ return;
+ }
+
+ _queue.Enqueue(value);
+ }
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ lock (_parent._gate)
+ {
+ _parent._observer.OnError(error);
+ _parent.Dispose();
+ }
+ }
+
+ public void OnCompleted()
+ {
+ lock (_parent._gate)
+ {
+ Done = true;
+
+ if (_other.Done)
+ {
+ _parent._observer.OnCompleted();
+ _parent.Dispose();
+ return;
+ }
+ else
+ {
+ _self.Dispose();
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ _queue.Clear();
+ }
+ }
+ }
+
+ class ε : Sink<TResult>, IObserver<TFirst>
+ {
+ private readonly Zip<TFirst, TSecond, TResult> _parent;
+
+ public ε(Zip<TFirst, TSecond, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private IEnumerator<TSecond> _rightEnumerator;
+
+ public IDisposable Run()
+ {
+ //
+ // Notice the evaluation order of obtaining the enumerator and subscribing to the
+ // observable sequence is reversed compared to the operator's signature. This is
+ // required to make sure the enumerator is available as soon as the observer can
+ // be called. Otherwise, we end up having a race for the initialization and use
+ // of the _rightEnumerator field.
+ //
+ try
+ {
+ _rightEnumerator = _parent._secondE.GetEnumerator();
+ }
+ catch (Exception exception)
+ {
+ base._observer.OnError(exception);
+ base.Dispose();
+ return Disposable.Empty;
+ }
+
+ var leftSubscription = _parent._first.SubscribeSafe(this);
+
+ return new CompositeDisposable(leftSubscription, _rightEnumerator);
+ }
+
+ public void OnNext(TFirst value)
+ {
+ var hasNext = false;
+ try
+ {
+ hasNext = _rightEnumerator.MoveNext();
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ if (hasNext)
+ {
+ var right = default(TSecond);
+ try
+ {
+ right = _rightEnumerator.Current;
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ TResult result;
+ try
+ {
+ result = _parent._resultSelector(value, right);
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(result);
+ }
+ else
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void OnCompleted()
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ #endregion
+
+ #region [3,16]-ary
+
+ /* The following code is generated by a tool checked in to $/.../Source/Tools/CodeGenerators. */
+
+ #region Zip auto-generated code (6/10/2012 8:13:21 PM)
+
+ class Zip<T1, T2, T3, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly Func<T1, T2, T3, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, Func<T1, T2, T3, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(3, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[3];
+ for (int i = 0; i < 3; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly Func<T1, T2, T3, T4, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, Func<T1, T2, T3, T4, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(4, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[4];
+ for (int i = 0; i < 4; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue());
+ }
+ }
+ }
+
+#if !NO_LARGEARITY
+ class Zip<T1, T2, T3, T4, T5, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly Func<T1, T2, T3, T4, T5, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, Func<T1, T2, T3, T4, T5, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(5, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[5];
+ for (int i = 0; i < 5; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly Func<T1, T2, T3, T4, T5, T6, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, Func<T1, T2, T3, T4, T5, T6, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(6, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[6];
+ for (int i = 0; i < 6; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, T7, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, Func<T1, T2, T3, T4, T5, T6, T7, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, T7, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, T7, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(7, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+ private ZipObserver<T7> _observer7;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[7];
+ for (int i = 0; i < 7; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new ZipObserver<T7>(_gate, this, 6, subscriptions[6]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+ base.Queues[6] = _observer7.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ _observer7.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue(), _observer7.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, T7, T8, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, T7, T8, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, T7, T8, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(8, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+ private ZipObserver<T7> _observer7;
+ private ZipObserver<T8> _observer8;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[8];
+ for (int i = 0; i < 8; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new ZipObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new ZipObserver<T8>(_gate, this, 7, subscriptions[7]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+ base.Queues[6] = _observer7.Values;
+ base.Queues[7] = _observer8.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ _observer7.Values.Clear();
+ _observer8.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue(), _observer7.Values.Dequeue(), _observer8.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(9, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+ private ZipObserver<T7> _observer7;
+ private ZipObserver<T8> _observer8;
+ private ZipObserver<T9> _observer9;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[9];
+ for (int i = 0; i < 9; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new ZipObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new ZipObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new ZipObserver<T9>(_gate, this, 8, subscriptions[8]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+ base.Queues[6] = _observer7.Values;
+ base.Queues[7] = _observer8.Values;
+ base.Queues[8] = _observer9.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ _observer7.Values.Clear();
+ _observer8.Values.Clear();
+ _observer9.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue(), _observer7.Values.Dequeue(), _observer8.Values.Dequeue(), _observer9.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(10, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+ private ZipObserver<T7> _observer7;
+ private ZipObserver<T8> _observer8;
+ private ZipObserver<T9> _observer9;
+ private ZipObserver<T10> _observer10;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[10];
+ for (int i = 0; i < 10; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new ZipObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new ZipObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new ZipObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new ZipObserver<T10>(_gate, this, 9, subscriptions[9]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+ base.Queues[6] = _observer7.Values;
+ base.Queues[7] = _observer8.Values;
+ base.Queues[8] = _observer9.Values;
+ base.Queues[9] = _observer10.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ _observer7.Values.Clear();
+ _observer8.Values.Clear();
+ _observer9.Values.Clear();
+ _observer10.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue(), _observer7.Values.Dequeue(), _observer8.Values.Dequeue(), _observer9.Values.Dequeue(), _observer10.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(11, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+ private ZipObserver<T7> _observer7;
+ private ZipObserver<T8> _observer8;
+ private ZipObserver<T9> _observer9;
+ private ZipObserver<T10> _observer10;
+ private ZipObserver<T11> _observer11;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[11];
+ for (int i = 0; i < 11; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new ZipObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new ZipObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new ZipObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new ZipObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new ZipObserver<T11>(_gate, this, 10, subscriptions[10]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+ base.Queues[6] = _observer7.Values;
+ base.Queues[7] = _observer8.Values;
+ base.Queues[8] = _observer9.Values;
+ base.Queues[9] = _observer10.Values;
+ base.Queues[10] = _observer11.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ _observer7.Values.Clear();
+ _observer8.Values.Clear();
+ _observer9.Values.Clear();
+ _observer10.Values.Clear();
+ _observer11.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue(), _observer7.Values.Dequeue(), _observer8.Values.Dequeue(), _observer9.Values.Dequeue(), _observer10.Values.Dequeue(), _observer11.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly IObservable<T12> _source12;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _source12 = source12;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(12, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+ private ZipObserver<T7> _observer7;
+ private ZipObserver<T8> _observer8;
+ private ZipObserver<T9> _observer9;
+ private ZipObserver<T10> _observer10;
+ private ZipObserver<T11> _observer11;
+ private ZipObserver<T12> _observer12;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[12];
+ for (int i = 0; i < 12; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new ZipObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new ZipObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new ZipObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new ZipObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new ZipObserver<T11>(_gate, this, 10, subscriptions[10]);
+ _observer12 = new ZipObserver<T12>(_gate, this, 11, subscriptions[11]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+ base.Queues[6] = _observer7.Values;
+ base.Queues[7] = _observer8.Values;
+ base.Queues[8] = _observer9.Values;
+ base.Queues[9] = _observer10.Values;
+ base.Queues[10] = _observer11.Values;
+ base.Queues[11] = _observer12.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+ subscriptions[11].Disposable = _parent._source12.SubscribeSafe(_observer12);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ _observer7.Values.Clear();
+ _observer8.Values.Clear();
+ _observer9.Values.Clear();
+ _observer10.Values.Clear();
+ _observer11.Values.Clear();
+ _observer12.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue(), _observer7.Values.Dequeue(), _observer8.Values.Dequeue(), _observer9.Values.Dequeue(), _observer10.Values.Dequeue(), _observer11.Values.Dequeue(), _observer12.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly IObservable<T12> _source12;
+ private readonly IObservable<T13> _source13;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _source12 = source12;
+ _source13 = source13;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(13, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+ private ZipObserver<T7> _observer7;
+ private ZipObserver<T8> _observer8;
+ private ZipObserver<T9> _observer9;
+ private ZipObserver<T10> _observer10;
+ private ZipObserver<T11> _observer11;
+ private ZipObserver<T12> _observer12;
+ private ZipObserver<T13> _observer13;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[13];
+ for (int i = 0; i < 13; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new ZipObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new ZipObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new ZipObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new ZipObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new ZipObserver<T11>(_gate, this, 10, subscriptions[10]);
+ _observer12 = new ZipObserver<T12>(_gate, this, 11, subscriptions[11]);
+ _observer13 = new ZipObserver<T13>(_gate, this, 12, subscriptions[12]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+ base.Queues[6] = _observer7.Values;
+ base.Queues[7] = _observer8.Values;
+ base.Queues[8] = _observer9.Values;
+ base.Queues[9] = _observer10.Values;
+ base.Queues[10] = _observer11.Values;
+ base.Queues[11] = _observer12.Values;
+ base.Queues[12] = _observer13.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+ subscriptions[11].Disposable = _parent._source12.SubscribeSafe(_observer12);
+ subscriptions[12].Disposable = _parent._source13.SubscribeSafe(_observer13);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ _observer7.Values.Clear();
+ _observer8.Values.Clear();
+ _observer9.Values.Clear();
+ _observer10.Values.Clear();
+ _observer11.Values.Clear();
+ _observer12.Values.Clear();
+ _observer13.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue(), _observer7.Values.Dequeue(), _observer8.Values.Dequeue(), _observer9.Values.Dequeue(), _observer10.Values.Dequeue(), _observer11.Values.Dequeue(), _observer12.Values.Dequeue(), _observer13.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly IObservable<T12> _source12;
+ private readonly IObservable<T13> _source13;
+ private readonly IObservable<T14> _source14;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _source12 = source12;
+ _source13 = source13;
+ _source14 = source14;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(14, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+ private ZipObserver<T7> _observer7;
+ private ZipObserver<T8> _observer8;
+ private ZipObserver<T9> _observer9;
+ private ZipObserver<T10> _observer10;
+ private ZipObserver<T11> _observer11;
+ private ZipObserver<T12> _observer12;
+ private ZipObserver<T13> _observer13;
+ private ZipObserver<T14> _observer14;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[14];
+ for (int i = 0; i < 14; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new ZipObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new ZipObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new ZipObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new ZipObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new ZipObserver<T11>(_gate, this, 10, subscriptions[10]);
+ _observer12 = new ZipObserver<T12>(_gate, this, 11, subscriptions[11]);
+ _observer13 = new ZipObserver<T13>(_gate, this, 12, subscriptions[12]);
+ _observer14 = new ZipObserver<T14>(_gate, this, 13, subscriptions[13]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+ base.Queues[6] = _observer7.Values;
+ base.Queues[7] = _observer8.Values;
+ base.Queues[8] = _observer9.Values;
+ base.Queues[9] = _observer10.Values;
+ base.Queues[10] = _observer11.Values;
+ base.Queues[11] = _observer12.Values;
+ base.Queues[12] = _observer13.Values;
+ base.Queues[13] = _observer14.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+ subscriptions[11].Disposable = _parent._source12.SubscribeSafe(_observer12);
+ subscriptions[12].Disposable = _parent._source13.SubscribeSafe(_observer13);
+ subscriptions[13].Disposable = _parent._source14.SubscribeSafe(_observer14);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ _observer7.Values.Clear();
+ _observer8.Values.Clear();
+ _observer9.Values.Clear();
+ _observer10.Values.Clear();
+ _observer11.Values.Clear();
+ _observer12.Values.Clear();
+ _observer13.Values.Clear();
+ _observer14.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue(), _observer7.Values.Dequeue(), _observer8.Values.Dequeue(), _observer9.Values.Dequeue(), _observer10.Values.Dequeue(), _observer11.Values.Dequeue(), _observer12.Values.Dequeue(), _observer13.Values.Dequeue(), _observer14.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly IObservable<T12> _source12;
+ private readonly IObservable<T13> _source13;
+ private readonly IObservable<T14> _source14;
+ private readonly IObservable<T15> _source15;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, IObservable<T15> source15, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _source12 = source12;
+ _source13 = source13;
+ _source14 = source14;
+ _source15 = source15;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(15, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+ private ZipObserver<T7> _observer7;
+ private ZipObserver<T8> _observer8;
+ private ZipObserver<T9> _observer9;
+ private ZipObserver<T10> _observer10;
+ private ZipObserver<T11> _observer11;
+ private ZipObserver<T12> _observer12;
+ private ZipObserver<T13> _observer13;
+ private ZipObserver<T14> _observer14;
+ private ZipObserver<T15> _observer15;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[15];
+ for (int i = 0; i < 15; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new ZipObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new ZipObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new ZipObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new ZipObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new ZipObserver<T11>(_gate, this, 10, subscriptions[10]);
+ _observer12 = new ZipObserver<T12>(_gate, this, 11, subscriptions[11]);
+ _observer13 = new ZipObserver<T13>(_gate, this, 12, subscriptions[12]);
+ _observer14 = new ZipObserver<T14>(_gate, this, 13, subscriptions[13]);
+ _observer15 = new ZipObserver<T15>(_gate, this, 14, subscriptions[14]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+ base.Queues[6] = _observer7.Values;
+ base.Queues[7] = _observer8.Values;
+ base.Queues[8] = _observer9.Values;
+ base.Queues[9] = _observer10.Values;
+ base.Queues[10] = _observer11.Values;
+ base.Queues[11] = _observer12.Values;
+ base.Queues[12] = _observer13.Values;
+ base.Queues[13] = _observer14.Values;
+ base.Queues[14] = _observer15.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+ subscriptions[11].Disposable = _parent._source12.SubscribeSafe(_observer12);
+ subscriptions[12].Disposable = _parent._source13.SubscribeSafe(_observer13);
+ subscriptions[13].Disposable = _parent._source14.SubscribeSafe(_observer14);
+ subscriptions[14].Disposable = _parent._source15.SubscribeSafe(_observer15);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ _observer7.Values.Clear();
+ _observer8.Values.Clear();
+ _observer9.Values.Clear();
+ _observer10.Values.Clear();
+ _observer11.Values.Clear();
+ _observer12.Values.Clear();
+ _observer13.Values.Clear();
+ _observer14.Values.Clear();
+ _observer15.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue(), _observer7.Values.Dequeue(), _observer8.Values.Dequeue(), _observer9.Values.Dequeue(), _observer10.Values.Dequeue(), _observer11.Values.Dequeue(), _observer12.Values.Dequeue(), _observer13.Values.Dequeue(), _observer14.Values.Dequeue(), _observer15.Values.Dequeue());
+ }
+ }
+ }
+
+ class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> : Producer<TResult>
+ {
+ private readonly IObservable<T1> _source1;
+ private readonly IObservable<T2> _source2;
+ private readonly IObservable<T3> _source3;
+ private readonly IObservable<T4> _source4;
+ private readonly IObservable<T5> _source5;
+ private readonly IObservable<T6> _source6;
+ private readonly IObservable<T7> _source7;
+ private readonly IObservable<T8> _source8;
+ private readonly IObservable<T9> _source9;
+ private readonly IObservable<T10> _source10;
+ private readonly IObservable<T11> _source11;
+ private readonly IObservable<T12> _source12;
+ private readonly IObservable<T13> _source13;
+ private readonly IObservable<T14> _source14;
+ private readonly IObservable<T15> _source15;
+ private readonly IObservable<T16> _source16;
+ private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> _resultSelector;
+
+ public Zip(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, IObservable<T15> source15, IObservable<T16> source16, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> resultSelector)
+ {
+ _source1 = source1;
+ _source2 = source2;
+ _source3 = source3;
+ _source4 = source4;
+ _source5 = source5;
+ _source6 = source6;
+ _source7 = source7;
+ _source8 = source8;
+ _source9 = source9;
+ _source10 = source10;
+ _source11 = source11;
+ _source12 = source12;
+ _source13 = source13;
+ _source14 = source14;
+ _source15 = source15;
+ _source16 = source16;
+ _resultSelector = resultSelector;
+ }
+
+ protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : ZipSink<TResult>
+ {
+ private readonly Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> _parent;
+
+ public _(Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
+ : base(16, observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private ZipObserver<T1> _observer1;
+ private ZipObserver<T2> _observer2;
+ private ZipObserver<T3> _observer3;
+ private ZipObserver<T4> _observer4;
+ private ZipObserver<T5> _observer5;
+ private ZipObserver<T6> _observer6;
+ private ZipObserver<T7> _observer7;
+ private ZipObserver<T8> _observer8;
+ private ZipObserver<T9> _observer9;
+ private ZipObserver<T10> _observer10;
+ private ZipObserver<T11> _observer11;
+ private ZipObserver<T12> _observer12;
+ private ZipObserver<T13> _observer13;
+ private ZipObserver<T14> _observer14;
+ private ZipObserver<T15> _observer15;
+ private ZipObserver<T16> _observer16;
+
+ public IDisposable Run()
+ {
+ var subscriptions = new SingleAssignmentDisposable[16];
+ for (int i = 0; i < 16; i++)
+ subscriptions[i] = new SingleAssignmentDisposable();
+
+ _observer1 = new ZipObserver<T1>(_gate, this, 0, subscriptions[0]);
+ _observer2 = new ZipObserver<T2>(_gate, this, 1, subscriptions[1]);
+ _observer3 = new ZipObserver<T3>(_gate, this, 2, subscriptions[2]);
+ _observer4 = new ZipObserver<T4>(_gate, this, 3, subscriptions[3]);
+ _observer5 = new ZipObserver<T5>(_gate, this, 4, subscriptions[4]);
+ _observer6 = new ZipObserver<T6>(_gate, this, 5, subscriptions[5]);
+ _observer7 = new ZipObserver<T7>(_gate, this, 6, subscriptions[6]);
+ _observer8 = new ZipObserver<T8>(_gate, this, 7, subscriptions[7]);
+ _observer9 = new ZipObserver<T9>(_gate, this, 8, subscriptions[8]);
+ _observer10 = new ZipObserver<T10>(_gate, this, 9, subscriptions[9]);
+ _observer11 = new ZipObserver<T11>(_gate, this, 10, subscriptions[10]);
+ _observer12 = new ZipObserver<T12>(_gate, this, 11, subscriptions[11]);
+ _observer13 = new ZipObserver<T13>(_gate, this, 12, subscriptions[12]);
+ _observer14 = new ZipObserver<T14>(_gate, this, 13, subscriptions[13]);
+ _observer15 = new ZipObserver<T15>(_gate, this, 14, subscriptions[14]);
+ _observer16 = new ZipObserver<T16>(_gate, this, 15, subscriptions[15]);
+
+ base.Queues[0] = _observer1.Values;
+ base.Queues[1] = _observer2.Values;
+ base.Queues[2] = _observer3.Values;
+ base.Queues[3] = _observer4.Values;
+ base.Queues[4] = _observer5.Values;
+ base.Queues[5] = _observer6.Values;
+ base.Queues[6] = _observer7.Values;
+ base.Queues[7] = _observer8.Values;
+ base.Queues[8] = _observer9.Values;
+ base.Queues[9] = _observer10.Values;
+ base.Queues[10] = _observer11.Values;
+ base.Queues[11] = _observer12.Values;
+ base.Queues[12] = _observer13.Values;
+ base.Queues[13] = _observer14.Values;
+ base.Queues[14] = _observer15.Values;
+ base.Queues[15] = _observer16.Values;
+
+ subscriptions[0].Disposable = _parent._source1.SubscribeSafe(_observer1);
+ subscriptions[1].Disposable = _parent._source2.SubscribeSafe(_observer2);
+ subscriptions[2].Disposable = _parent._source3.SubscribeSafe(_observer3);
+ subscriptions[3].Disposable = _parent._source4.SubscribeSafe(_observer4);
+ subscriptions[4].Disposable = _parent._source5.SubscribeSafe(_observer5);
+ subscriptions[5].Disposable = _parent._source6.SubscribeSafe(_observer6);
+ subscriptions[6].Disposable = _parent._source7.SubscribeSafe(_observer7);
+ subscriptions[7].Disposable = _parent._source8.SubscribeSafe(_observer8);
+ subscriptions[8].Disposable = _parent._source9.SubscribeSafe(_observer9);
+ subscriptions[9].Disposable = _parent._source10.SubscribeSafe(_observer10);
+ subscriptions[10].Disposable = _parent._source11.SubscribeSafe(_observer11);
+ subscriptions[11].Disposable = _parent._source12.SubscribeSafe(_observer12);
+ subscriptions[12].Disposable = _parent._source13.SubscribeSafe(_observer13);
+ subscriptions[13].Disposable = _parent._source14.SubscribeSafe(_observer14);
+ subscriptions[14].Disposable = _parent._source15.SubscribeSafe(_observer15);
+ subscriptions[15].Disposable = _parent._source16.SubscribeSafe(_observer16);
+
+ return new CompositeDisposable(subscriptions)
+ {
+ Disposable.Create(() =>
+ {
+ _observer1.Values.Clear();
+ _observer2.Values.Clear();
+ _observer3.Values.Clear();
+ _observer4.Values.Clear();
+ _observer5.Values.Clear();
+ _observer6.Values.Clear();
+ _observer7.Values.Clear();
+ _observer8.Values.Clear();
+ _observer9.Values.Clear();
+ _observer10.Values.Clear();
+ _observer11.Values.Clear();
+ _observer12.Values.Clear();
+ _observer13.Values.Clear();
+ _observer14.Values.Clear();
+ _observer15.Values.Clear();
+ _observer16.Values.Clear();
+ })
+ };
+ }
+
+ protected override TResult GetResult()
+ {
+ return _parent._resultSelector(_observer1.Values.Dequeue(), _observer2.Values.Dequeue(), _observer3.Values.Dequeue(), _observer4.Values.Dequeue(), _observer5.Values.Dequeue(), _observer6.Values.Dequeue(), _observer7.Values.Dequeue(), _observer8.Values.Dequeue(), _observer9.Values.Dequeue(), _observer10.Values.Dequeue(), _observer11.Values.Dequeue(), _observer12.Values.Dequeue(), _observer13.Values.Dequeue(), _observer14.Values.Dequeue(), _observer15.Values.Dequeue(), _observer16.Values.Dequeue());
+ }
+ }
+ }
+
+#endif
+
+ #endregion
+
+ #region Helpers for n-ary overloads
+
+ interface IZip
+ {
+ void Next(int index);
+ void Fail(Exception error);
+ void Done(int index);
+ }
+
+ abstract class ZipSink<TResult> : Sink<TResult>, IZip
+ {
+ protected readonly object _gate;
+
+ private readonly ICollection[] _queues;
+ private readonly bool[] _isDone;
+
+ public ZipSink(int arity, IObserver<TResult> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _gate = new object();
+
+ _isDone = new bool[arity];
+ _queues = new ICollection[arity];
+ }
+
+ public ICollection[] Queues
+ {
+ get { return _queues; }
+ }
+
+ public void Next(int index)
+ {
+ var hasValueAll = true;
+ foreach (var queue in _queues)
+ {
+ if (queue.Count == 0)
+ {
+ hasValueAll = false;
+ break;
+ }
+ }
+
+ if (hasValueAll)
+ {
+ var res = default(TResult);
+ try
+ {
+ res = GetResult();
+ }
+ catch (Exception ex)
+ {
+ base._observer.OnError(ex);
+ base.Dispose();
+ return;
+ }
+
+ base._observer.OnNext(res);
+ }
+ else
+ {
+ var allOthersDone = true;
+ for (int i = 0; i < _isDone.Length; i++)
+ {
+ if (i != index && !_isDone[i])
+ {
+ allOthersDone = false;
+ break;
+ }
+ }
+
+ if (allOthersDone)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ }
+ }
+ }
+
+ protected abstract TResult GetResult();
+
+ public void Fail(Exception error)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+
+ public void Done(int index)
+ {
+ _isDone[index] = true;
+
+ var allDone = true;
+ foreach (var isDone in _isDone)
+ {
+ if (!isDone)
+ {
+ allDone = false;
+ break;
+ }
+ }
+
+ if (allDone)
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ return;
+ }
+ }
+ }
+
+ class ZipObserver<T> : IObserver<T>
+ {
+ private readonly object _gate;
+ private readonly IZip _parent;
+ private readonly int _index;
+ private readonly IDisposable _self;
+ private readonly Queue<T> _values;
+
+ public ZipObserver(object gate, IZip parent, int index, IDisposable self)
+ {
+ _gate = gate;
+ _parent = parent;
+ _index = index;
+ _self = self;
+ _values = new Queue<T>();
+ }
+
+ public Queue<T> Values
+ {
+ get { return _values; }
+ }
+
+ public void OnNext(T value)
+ {
+ lock (_gate)
+ {
+ _values.Enqueue(value);
+ _parent.Next(_index);
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ _self.Dispose();
+
+ lock (_gate)
+ {
+ _parent.Fail(error);
+ }
+ }
+
+ public void OnCompleted()
+ {
+ _self.Dispose();
+
+ lock (_gate)
+ {
+ _parent.Done(_index);
+ }
+ }
+ }
+
+ #endregion
+
+ #endregion
+
+ #region N-ary
+
+ class Zip<TSource> : Producer<IList<TSource>>
+ {
+ private readonly IEnumerable<IObservable<TSource>> _sources;
+
+ public Zip(IEnumerable<IObservable<TSource>> sources)
+ {
+ _sources = sources;
+ }
+
+ protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
+ {
+ var sink = new _(this, observer, cancel);
+ setSink(sink);
+ return sink.Run();
+ }
+
+ class _ : Sink<IList<TSource>>
+ {
+ private readonly Zip<TSource> _parent;
+
+ public _(Zip<TSource> parent, IObserver<IList<TSource>> observer, IDisposable cancel)
+ : base(observer, cancel)
+ {
+ _parent = parent;
+ }
+
+ private object _gate;
+ private Queue<TSource>[] _queues;
+ private bool[] _isDone;
+ private IDisposable[] _subscriptions;
+
+ public IDisposable Run()
+ {
+ var srcs = _parent._sources.ToArray();
+
+ var N = srcs.Length;
+
+ _queues = new Queue<TSource>[N];
+ for (int i = 0; i < N; i++)
+ _queues[i] = new Queue<TSource>();
+
+ _isDone = new bool[N];
+
+ _subscriptions = new SingleAssignmentDisposable[N];
+
+ _gate = new object();
+
+ for (int i = 0; i < N; i++)
+ {
+ var j = i;
+
+ var d = new SingleAssignmentDisposable();
+ _subscriptions[j] = d;
+
+ var o = new O(this, j);
+ d.Disposable = srcs[j].SubscribeSafe(o);
+ }
+
+ return new CompositeDisposable(_subscriptions) { Disposable.Create(() => { foreach (var q in _queues) q.Clear(); }) };
+ }
+
+ private void OnNext(int index, TSource value)
+ {
+ lock (_gate)
+ {
+ _queues[index].Enqueue(value);
+
+ if (_queues.All(q => q.Count > 0))
+ {
+ var res = _queues.Select(q => q.Dequeue()).ToList();
+ base._observer.OnNext(res);
+ }
+ else if (_isDone.Where((x, i) => i != index).All(Stubs<bool>.I))
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ return;
+ }
+ }
+ }
+
+ private void OnError(Exception error)
+ {
+ lock (_gate)
+ {
+ base._observer.OnError(error);
+ base.Dispose();
+ }
+ }
+
+ private void OnCompleted(int index)
+ {
+ lock (_gate)
+ {
+ _isDone[index] = true;
+
+ if (_isDone.All(Stubs<bool>.I))
+ {
+ base._observer.OnCompleted();
+ base.Dispose();
+ return;
+ }
+ else
+ {
+ _subscriptions[index].Dispose();
+ }
+ }
+ }
+
+ class O : IObserver<TSource>
+ {
+ private readonly _ _parent;
+ private readonly int _index;
+
+ public O(_ parent, int index)
+ {
+ _parent = parent;
+ _index = index;
+ }
+
+ public void OnNext(TSource value)
+ {
+ _parent.OnNext(_index, value);
+ }
+
+ public void OnError(Exception error)
+ {
+ _parent.OnError(error);
+ }
+
+ public void OnCompleted()
+ {
+ _parent.OnCompleted(_index);
+ }
+ }
+ }
+ }
+
+ #endregion
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/_.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/_.cs
new file mode 100644
index 0000000..d4b0dbc
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/_.cs
@@ -0,0 +1,9 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !NO_PERF
+using System;
+
+namespace System.Reactive.Linq.Observαble
+{
+}
+#endif
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Aggregates.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Aggregates.cs
new file mode 100644
index 0000000..739fc2d
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Aggregates.cs
@@ -0,0 +1,1662 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ internal partial class QueryLanguage
+ {
+ #region + Aggregate +
+
+ public virtual IObservable<TAccumulate> Aggregate<TSource, TAccumulate>(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
+ {
+#if !NO_PERF
+ return new Aggregate<TSource, TAccumulate, TAccumulate>(source, seed, accumulator, Stubs<TAccumulate>.I);
+#else
+ return source.Scan(seed, accumulator).StartWith(seed).Final();
+#endif
+ }
+
+ public virtual IObservable<TResult> Aggregate<TSource, TAccumulate, TResult>(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector)
+ {
+#if !NO_PERF
+ return new Aggregate<TSource, TAccumulate, TResult>(source, seed, accumulator, resultSelector);
+#else
+ return Aggregate(source, seed, accumulator).Select(resultSelector);
+#endif
+ }
+
+ public virtual IObservable<TSource> Aggregate<TSource>(IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
+ {
+#if !NO_PERF
+ return new Aggregate<TSource>(source, accumulator);
+#else
+ return source.Scan(accumulator).Final();
+#endif
+ }
+
+ public virtual IObservable<double> Average<TSource>(IObservable<TSource> source, Func<TSource, double> selector)
+ {
+ return Average(Select(source, selector));
+ }
+
+ public virtual IObservable<float> Average<TSource>(IObservable<TSource> source, Func<TSource, float> selector)
+ {
+ return Average(Select(source, selector));
+ }
+
+ public virtual IObservable<decimal> Average<TSource>(IObservable<TSource> source, Func<TSource, decimal> selector)
+ {
+ return Average(Select(source, selector));
+ }
+
+ public virtual IObservable<double> Average<TSource>(IObservable<TSource> source, Func<TSource, int> selector)
+ {
+ return Average(Select(source, selector));
+ }
+
+ public virtual IObservable<double> Average<TSource>(IObservable<TSource> source, Func<TSource, long> selector)
+ {
+ return Average(Select(source, selector));
+ }
+
+ public virtual IObservable<double?> Average<TSource>(IObservable<TSource> source, Func<TSource, double?> selector)
+ {
+ return Average(Select(source, selector));
+ }
+
+ public virtual IObservable<float?> Average<TSource>(IObservable<TSource> source, Func<TSource, float?> selector)
+ {
+ return Average(Select(source, selector));
+ }
+
+ public virtual IObservable<decimal?> Average<TSource>(IObservable<TSource> source, Func<TSource, decimal?> selector)
+ {
+ return Average(Select(source, selector));
+ }
+
+ public virtual IObservable<double?> Average<TSource>(IObservable<TSource> source, Func<TSource, int?> selector)
+ {
+ return Average(Select(source, selector));
+ }
+
+ public virtual IObservable<double?> Average<TSource>(IObservable<TSource> source, Func<TSource, long?> selector)
+ {
+ return Average(Select(source, selector));
+ }
+
+ #endregion
+
+ #region + All +
+
+ public virtual IObservable<bool> All<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new All<TSource>(source, predicate);
+#else
+ return source.Where(v => !(predicate(v))).Any().Select(b => !b);
+#endif
+ }
+
+ #endregion
+
+ #region + Any +
+
+ public virtual IObservable<bool> Any<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new Any<TSource>(source);
+#else
+ return new AnonymousObservable<bool>(observer => source.Subscribe(
+ _ =>
+ {
+ observer.OnNext(true);
+ observer.OnCompleted();
+ },
+ observer.OnError,
+ () =>
+ {
+ observer.OnNext(false);
+ observer.OnCompleted();
+ }));
+#endif
+ }
+
+ public virtual IObservable<bool> Any<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new Any<TSource>(source, predicate);
+#else
+ return source.Where(predicate).Any();
+#endif
+ }
+
+ #endregion
+
+ #region + Average +
+
+ public virtual IObservable<double> Average(IObservable<double> source)
+ {
+#if !NO_PERF
+ return new AverageDouble(source);
+#else
+ return source.Scan(new { sum = 0.0, count = 0L },
+ (prev, cur) => new { sum = prev.sum + cur, count = checked(prev.count + 1) })
+ .Final()
+ .Select(s => s.sum / (double)s.count);
+#endif
+ }
+
+ public virtual IObservable<float> Average(IObservable<float> source)
+ {
+#if !NO_PERF
+ return new AverageSingle(source);
+#else
+ return source.Scan(new { sum = 0F, count = 0L }, // NOTE: Uses a different accumulator type (float), *not* conform LINQ to Objects.
+ (prev, cur) => new { sum = prev.sum + cur, count = checked(prev.count + 1) })
+ .Final()
+ .Select(s => s.sum / (float)s.count);
+#endif
+ }
+
+ public virtual IObservable<decimal> Average(IObservable<decimal> source)
+ {
+#if !NO_PERF
+ return new AverageDecimal(source);
+#else
+ return source.Scan(new { sum = 0M, count = 0L },
+ (prev, cur) => new { sum = prev.sum + cur, count = checked(prev.count + 1) })
+ .Final()
+ .Select(s => s.sum / (decimal)s.count);
+#endif
+ }
+
+ public virtual IObservable<double> Average(IObservable<int> source)
+ {
+#if !NO_PERF
+ return new AverageInt32(source);
+#else
+ return source.Scan(new { sum = 0L, count = 0L },
+ (prev, cur) => new { sum = checked(prev.sum + cur), count = checked(prev.count + 1) })
+ .Final()
+ .Select(s => (double)s.sum / (double)s.count);
+#endif
+ }
+
+ public virtual IObservable<double> Average(IObservable<long> source)
+ {
+#if !NO_PERF
+ return new AverageInt64(source);
+#else
+ return source.Scan(new { sum = 0L, count = 0L },
+ (prev, cur) => new { sum = checked(prev.sum + cur), count = checked(prev.count + 1) })
+ .Final()
+ .Select(s => (double)s.sum / (double)s.count);
+#endif
+ }
+
+ public virtual IObservable<double?> Average(IObservable<double?> source)
+ {
+#if !NO_PERF
+ return new AverageDoubleNullable(source);
+#else
+ return source.Aggregate(new { sum = new double?(0.0), count = 0L },
+ (prev, cur) => cur != null ? new { sum = prev.sum + cur.GetValueOrDefault(), count = checked(prev.count + 1) } : prev)
+ .Select(s => s.count == 0 ? default(double?) : (double?)s.sum / (double)s.count);
+#endif
+ }
+
+ public virtual IObservable<float?> Average(IObservable<float?> source)
+ {
+#if !NO_PERF
+ return new AverageSingleNullable(source);
+#else
+ return source.Aggregate(new { sum = new float?(0f), count = 0L }, // NOTE: Uses a different accumulator type (float), *not* conform LINQ to Objects.
+ (prev, cur) => cur != null ? new { sum = prev.sum + cur.GetValueOrDefault(), count = checked(prev.count + 1) } : prev)
+ .Select(s => s.count == 0 ? default(float?) : (float?)s.sum / (float)s.count);
+#endif
+ }
+
+ public virtual IObservable<decimal?> Average(IObservable<decimal?> source)
+ {
+#if !NO_PERF
+ return new AverageDecimalNullable(source);
+#else
+ return source.Aggregate(new { sum = new decimal?(0M), count = 0L },
+ (prev, cur) => cur != null ? new { sum = prev.sum + cur.GetValueOrDefault(), count = checked(prev.count + 1) } : prev)
+ .Select(s => s.count == 0 ? default(decimal?) : (decimal?)s.sum / (decimal)s.count);
+#endif
+ }
+
+ public virtual IObservable<double?> Average(IObservable<int?> source)
+ {
+#if !NO_PERF
+ return new AverageInt32Nullable(source);
+#else
+ return source.Aggregate(new { sum = new long?(0), count = 0L },
+ (prev, cur) => cur != null ? new { sum = checked(prev.sum + cur.GetValueOrDefault()), count = checked(prev.count + 1) } : prev)
+ .Select(s => s.count == 0 ? default(double?) : (double?)s.sum / s.count);
+#endif
+ }
+
+ public virtual IObservable<double?> Average(IObservable<long?> source)
+ {
+#if !NO_PERF
+ return new AverageInt64Nullable(source);
+#else
+ return source.Aggregate(new { sum = new long?(0), count = 0L },
+ (prev, cur) => cur != null ? new { sum = checked(prev.sum + cur.GetValueOrDefault()), count = checked(prev.count + 1) } : prev)
+ .Select(s => s.count == 0 ? default(double?): (double?)s.sum / s.count);
+#endif
+ }
+
+ #endregion
+
+ #region + Contains +
+
+ public virtual IObservable<bool> Contains<TSource>(IObservable<TSource> source, TSource value)
+ {
+#if !NO_PERF
+ return new Contains<TSource>(source, value, EqualityComparer<TSource>.Default);
+#else
+ return Contains_<TSource>(source, value, EqualityComparer<TSource>.Default);
+#endif
+ }
+
+ public virtual IObservable<bool> Contains<TSource>(IObservable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
+ {
+#if !NO_PERF
+ return new Contains<TSource>(source, value, comparer);
+#else
+ return Contains_<TSource>(source, value, comparer);
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<bool> Contains_<TSource>(IObservable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
+ {
+ return source.Where(v => comparer.Equals(v, value)).Any();
+ }
+#endif
+
+ #endregion
+
+ #region + Count +
+
+ public virtual IObservable<int> Count<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new Count<TSource>(source);
+#else
+ return source.Aggregate(0, (count, _) => checked(count + 1));
+#endif
+ }
+
+ public virtual IObservable<int> Count<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new Count<TSource>(source, predicate);
+#else
+ return source.Where(predicate).Aggregate(0, (count, _) => checked(count + 1));
+#endif
+ }
+
+ #endregion
+
+ #region + ElementAt +
+
+ public virtual IObservable<TSource> ElementAt<TSource>(IObservable<TSource> source, int index)
+ {
+#if !NO_PERF
+ return new ElementAt<TSource>(source, index, true);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ int i = index;
+ return source.Subscribe(
+ x =>
+ {
+ if (i == 0)
+ {
+ observer.OnNext(x);
+ observer.OnCompleted();
+ }
+
+ i--;
+ },
+ observer.OnError,
+ () => observer.OnError(new ArgumentOutOfRangeException("index"))
+ );
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + ElementAtOrDefault +
+
+ public virtual IObservable<TSource> ElementAtOrDefault<TSource>(IObservable<TSource> source, int index)
+ {
+#if !NO_PERF
+ return new ElementAt<TSource>(source, index, false);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ int i = index;
+ return source.Subscribe(
+ x =>
+ {
+ if (i == 0)
+ {
+ observer.OnNext(x);
+ observer.OnCompleted();
+ }
+
+ i--;
+ },
+ observer.OnError,
+ () =>
+ {
+ observer.OnNext(default(TSource));
+ observer.OnCompleted();
+ }
+ );
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + FirstAsync +
+
+ public virtual IObservable<TSource> FirstAsync<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new FirstAsync<TSource>(source, null, true);
+#else
+ return FirstOrDefaultAsync_(source, true);
+#endif
+ }
+
+ public virtual IObservable<TSource> FirstAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new FirstAsync<TSource>(source, predicate, true);
+#else
+ return source.Where(predicate).FirstAsync();
+#endif
+ }
+
+ #endregion
+
+ #region + FirstAsyncOrDefaultAsync +
+
+ public virtual IObservable<TSource> FirstOrDefaultAsync<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new FirstAsync<TSource>(source, null, false);
+#else
+ return FirstOrDefaultAsync_(source, false);
+#endif
+ }
+
+ public virtual IObservable<TSource> FirstOrDefaultAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new FirstAsync<TSource>(source, predicate, false);
+#else
+ return source.Where(predicate).FirstOrDefaultAsync();
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TSource> FirstOrDefaultAsync_<TSource>(IObservable<TSource> source, bool throwOnEmpty)
+ {
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ return source.Subscribe(
+ x =>
+ {
+ observer.OnNext(x);
+ observer.OnCompleted();
+ },
+ observer.OnError,
+ () =>
+ {
+ if (throwOnEmpty)
+ {
+ observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ observer.OnNext(default(TSource));
+ observer.OnCompleted();
+ }
+ }
+ );
+ });
+ }
+#endif
+
+ #endregion
+
+ #region + IsEmpty +
+
+ public virtual IObservable<bool> IsEmpty<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new IsEmpty<TSource>(source);
+#else
+ return source.Any().Select(b => !b);
+#endif
+ }
+
+ #endregion
+
+ #region + LastAsync +
+
+ public virtual IObservable<TSource> LastAsync<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new LastAsync<TSource>(source, null, true);
+#else
+ return LastOrDefaultAsync_(source, true);
+#endif
+ }
+
+ public virtual IObservable<TSource> LastAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new LastAsync<TSource>(source, predicate, true);
+#else
+ return source.Where(predicate).LastAsync();
+#endif
+ }
+
+ #endregion
+
+ #region + LastOrDefaultAsync +
+
+ public virtual IObservable<TSource> LastOrDefaultAsync<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new LastAsync<TSource>(source, null, false);
+#else
+ return LastOrDefaultAsync_(source, false);
+#endif
+ }
+
+ public virtual IObservable<TSource> LastOrDefaultAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new LastAsync<TSource>(source, predicate, false);
+#else
+ return source.Where(predicate).LastOrDefaultAsync();
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TSource> LastOrDefaultAsync_<TSource>(IObservable<TSource> source, bool throwOnEmpty)
+ {
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var value = default(TSource);
+ var seenValue = false;
+
+ return source.Subscribe(
+ x =>
+ {
+ value = x;
+ seenValue = true;
+ },
+ observer.OnError,
+ () =>
+ {
+ if (throwOnEmpty && !seenValue)
+ {
+ observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ observer.OnNext(value);
+ observer.OnCompleted();
+ }
+ }
+ );
+ });
+ }
+#endif
+
+ #endregion
+
+ #region + LongCount +
+
+ public virtual IObservable<long> LongCount<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new LongCount<TSource>(source);
+#else
+ return source.Aggregate(0L, (count, _) => checked(count + 1));
+#endif
+ }
+
+ public virtual IObservable<long> LongCount<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new LongCount<TSource>(source, predicate);
+#else
+ return source.Where(predicate).Aggregate(0L, (count, _) => checked(count + 1));
+#endif
+ }
+
+ #endregion
+
+ #region + Max +
+
+ public virtual IObservable<TSource> Max<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ // BREAKING CHANGE v2 > v1.x - Behavior for reference types
+ return new Max<TSource>(source, Comparer<TSource>.Default);
+#else
+ return MaxBy(source, x => x).Select(x => x.First());
+#endif
+ }
+
+ public virtual IObservable<TSource> Max<TSource>(IObservable<TSource> source, IComparer<TSource> comparer)
+ {
+#if !NO_PERF
+ // BREAKING CHANGE v2 > v1.x - Behavior for reference types
+ return new Max<TSource>(source, comparer);
+#else
+ return MaxBy(source, x => x, comparer).Select(x => x.First());
+#endif
+ }
+
+ public virtual IObservable<double> Max(IObservable<double> source)
+ {
+#if !NO_PERF
+ return new MaxDouble(source);
+#else
+ return source.Scan(double.MinValue, Math.Max).Final();
+#endif
+ }
+
+ public virtual IObservable<float> Max(IObservable<float> source)
+ {
+#if !NO_PERF
+ return new MaxSingle(source);
+#else
+ return source.Scan(float.MinValue, Math.Max).Final();
+#endif
+ }
+
+ public virtual IObservable<decimal> Max(IObservable<decimal> source)
+ {
+#if !NO_PERF
+ return new MaxDecimal(source);
+#else
+ return source.Scan(decimal.MinValue, Math.Max).Final();
+#endif
+ }
+
+ public virtual IObservable<int> Max(IObservable<int> source)
+ {
+#if !NO_PERF
+ return new MaxInt32(source);
+#else
+ return source.Scan(int.MinValue, Math.Max).Final();
+#endif
+ }
+
+ public virtual IObservable<long> Max(IObservable<long> source)
+ {
+#if !NO_PERF
+ return new MaxInt64(source);
+#else
+ return source.Scan(long.MinValue, Math.Max).Final();
+#endif
+ }
+
+ public virtual IObservable<double?> Max(IObservable<double?> source)
+ {
+#if !NO_PERF
+ return new MaxDoubleNullable(source);
+#else
+ return source.Aggregate(new double?(), NullableMax);
+#endif
+ }
+
+ public virtual IObservable<float?> Max(IObservable<float?> source)
+ {
+#if !NO_PERF
+ return new MaxSingleNullable(source);
+#else
+ return source.Aggregate(new float?(), NullableMax);
+#endif
+ }
+
+ public virtual IObservable<decimal?> Max(IObservable<decimal?> source)
+ {
+#if !NO_PERF
+ return new MaxDecimalNullable(source);
+#else
+ return source.Aggregate(new decimal?(), NullableMax);
+#endif
+ }
+
+ public virtual IObservable<int?> Max(IObservable<int?> source)
+ {
+#if !NO_PERF
+ return new MaxInt32Nullable(source);
+#else
+ return source.Aggregate(new int?(), NullableMax);
+#endif
+ }
+
+ public virtual IObservable<long?> Max(IObservable<long?> source)
+ {
+#if !NO_PERF
+ return new MaxInt64Nullable(source);
+#else
+ return source.Aggregate(new long?(), NullableMax);
+#endif
+ }
+
+ public virtual IObservable<TResult> Max<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ public virtual IObservable<TResult> Max<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector, IComparer<TResult> comparer)
+ {
+ return Max(Select(source, selector), comparer);
+ }
+
+ public virtual IObservable<double> Max<TSource>(IObservable<TSource> source, Func<TSource, double> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ public virtual IObservable<float> Max<TSource>(IObservable<TSource> source, Func<TSource, float> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ public virtual IObservable<decimal> Max<TSource>(IObservable<TSource> source, Func<TSource, decimal> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ public virtual IObservable<int> Max<TSource>(IObservable<TSource> source, Func<TSource, int> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ public virtual IObservable<long> Max<TSource>(IObservable<TSource> source, Func<TSource, long> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ public virtual IObservable<double?> Max<TSource>(IObservable<TSource> source, Func<TSource, double?> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ public virtual IObservable<float?> Max<TSource>(IObservable<TSource> source, Func<TSource, float?> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ public virtual IObservable<decimal?> Max<TSource>(IObservable<TSource> source, Func<TSource, decimal?> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ public virtual IObservable<int?> Max<TSource>(IObservable<TSource> source, Func<TSource, int?> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ public virtual IObservable<long?> Max<TSource>(IObservable<TSource> source, Func<TSource, long?> selector)
+ {
+ return Max(Select(source, selector));
+ }
+
+ #endregion
+
+ #region + MaxBy +
+
+ public virtual IObservable<IList<TSource>> MaxBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+#if !NO_PERF
+ return new MaxBy<TSource, TKey>(source, keySelector, Comparer<TKey>.Default);
+#else
+ return MaxBy(source, keySelector, Comparer<TKey>.Default);
+#endif
+ }
+
+ public virtual IObservable<IList<TSource>> MaxBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
+ {
+#if !NO_PERF
+ return new MaxBy<TSource, TKey>(source, keySelector, comparer);
+#else
+ return ExtremaBy(source, keySelector, comparer);
+#endif
+ }
+
+ #endregion
+
+ #region + Min +
+
+ public virtual IObservable<TSource> Min<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ // BREAKING CHANGE v2 > v1.x - Behavior for reference types
+ return new Min<TSource>(source, Comparer<TSource>.Default);
+#else
+ return MinBy(source, x => x).Select(x => x.First());
+#endif
+ }
+
+ public virtual IObservable<TSource> Min<TSource>(IObservable<TSource> source, IComparer<TSource> comparer)
+ {
+#if !NO_PERF
+ // BREAKING CHANGE v2 > v1.x - Behavior for reference types
+ return new Min<TSource>(source, comparer);
+#else
+ return MinBy(source, x => x, comparer).Select(x => x.First());
+#endif
+ }
+
+ public virtual IObservable<double> Min(IObservable<double> source)
+ {
+#if !NO_PERF
+ return new MinDouble(source);
+#else
+ return source.Scan(double.MaxValue, Math.Min).Final();
+#endif
+ }
+
+ public virtual IObservable<float> Min(IObservable<float> source)
+ {
+#if !NO_PERF
+ return new MinSingle(source);
+#else
+ return source.Scan(float.MaxValue, Math.Min).Final();
+#endif
+ }
+
+ public virtual IObservable<decimal> Min(IObservable<decimal> source)
+ {
+#if !NO_PERF
+ return new MinDecimal(source);
+#else
+ return source.Scan(decimal.MaxValue, Math.Min).Final();
+#endif
+ }
+
+ public virtual IObservable<int> Min(IObservable<int> source)
+ {
+#if !NO_PERF
+ return new MinInt32(source);
+#else
+ return source.Scan(int.MaxValue, Math.Min).Final();
+#endif
+ }
+
+ public virtual IObservable<long> Min(IObservable<long> source)
+ {
+#if !NO_PERF
+ return new MinInt64(source);
+#else
+ return source.Scan(long.MaxValue, Math.Min).Final();
+#endif
+ }
+
+ public virtual IObservable<double?> Min(IObservable<double?> source)
+ {
+#if !NO_PERF
+ return new MinDoubleNullable(source);
+#else
+ return source.Aggregate(new double?(), NullableMin);
+#endif
+ }
+
+ public virtual IObservable<float?> Min(IObservable<float?> source)
+ {
+#if !NO_PERF
+ return new MinSingleNullable(source);
+#else
+ return source.Aggregate(new float?(), NullableMin);
+#endif
+ }
+
+ public virtual IObservable<decimal?> Min(IObservable<decimal?> source)
+ {
+#if !NO_PERF
+ return new MinDecimalNullable(source);
+#else
+ return source.Aggregate(new decimal?(), NullableMin);
+#endif
+ }
+
+ public virtual IObservable<int?> Min(IObservable<int?> source)
+ {
+#if !NO_PERF
+ return new MinInt32Nullable(source);
+#else
+ return source.Aggregate(new int?(), NullableMin);
+#endif
+ }
+
+ public virtual IObservable<long?> Min(IObservable<long?> source)
+ {
+#if !NO_PERF
+ return new MinInt64Nullable(source);
+#else
+ return source.Aggregate(new long?(), NullableMin);
+#endif
+ }
+
+ public virtual IObservable<TResult> Min<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ public virtual IObservable<TResult> Min<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector, IComparer<TResult> comparer)
+ {
+ return Min(Select(source, selector), comparer);
+ }
+
+ public virtual IObservable<double> Min<TSource>(IObservable<TSource> source, Func<TSource, double> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ public virtual IObservable<float> Min<TSource>(IObservable<TSource> source, Func<TSource, float> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ public virtual IObservable<decimal> Min<TSource>(IObservable<TSource> source, Func<TSource, decimal> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ public virtual IObservable<int> Min<TSource>(IObservable<TSource> source, Func<TSource, int> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ public virtual IObservable<long> Min<TSource>(IObservable<TSource> source, Func<TSource, long> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ public virtual IObservable<double?> Min<TSource>(IObservable<TSource> source, Func<TSource, double?> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ public virtual IObservable<float?> Min<TSource>(IObservable<TSource> source, Func<TSource, float?> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ public virtual IObservable<decimal?> Min<TSource>(IObservable<TSource> source, Func<TSource, decimal?> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ public virtual IObservable<int?> Min<TSource>(IObservable<TSource> source, Func<TSource, int?> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ public virtual IObservable<long?> Min<TSource>(IObservable<TSource> source, Func<TSource, long?> selector)
+ {
+ return Min(Select(source, selector));
+ }
+
+ #endregion
+
+ #region + MinBy +
+
+ public virtual IObservable<IList<TSource>> MinBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+#if !NO_PERF
+ return new MinBy<TSource, TKey>(source, keySelector, Comparer<TKey>.Default);
+#else
+ return MinBy(source, keySelector, Comparer<TKey>.Default);
+#endif
+ }
+
+ public virtual IObservable<IList<TSource>> MinBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
+ {
+#if !NO_PERF
+ return new MinBy<TSource, TKey>(source, keySelector, comparer);
+#else
+ return ExtremaBy(source, keySelector, new AnonymousComparer<TKey>((x, y) => comparer.Compare(x, y) * -1));
+#endif
+ }
+
+ #endregion
+
+ #region + SequenceEqual +
+
+ public virtual IObservable<bool> SequenceEqual<TSource>(IObservable<TSource> first, IObservable<TSource> second)
+ {
+#if !NO_PERF
+ return new SequenceEqual<TSource>(first, second, EqualityComparer<TSource>.Default);
+#else
+ return first.SequenceEqual(second, EqualityComparer<TSource>.Default);
+#endif
+ }
+
+ public virtual IObservable<bool> SequenceEqual<TSource>(IObservable<TSource> first, IObservable<TSource> second, IEqualityComparer<TSource> comparer)
+ {
+#if !NO_PERF
+ return new SequenceEqual<TSource>(first, second, comparer);
+#else
+ return new AnonymousObservable<bool>(observer =>
+ {
+ var gate = new object();
+ var donel = false;
+ var doner = false;
+ var ql = new Queue<TSource>();
+ var qr = new Queue<TSource>();
+
+ var subscription1 = first.Subscribe(
+ x =>
+ {
+ lock (gate)
+ {
+ if (qr.Count > 0)
+ {
+ var equal = false;
+ var v = qr.Dequeue();
+ try
+ {
+ equal = comparer.Equals(x, v);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+ if (!equal)
+ {
+ observer.OnNext(false);
+ observer.OnCompleted();
+ }
+ }
+ else if (doner)
+ {
+ observer.OnNext(false);
+ observer.OnCompleted();
+ }
+ else
+ ql.Enqueue(x);
+ }
+ },
+ observer.OnError,
+ () =>
+ {
+ lock (gate)
+ {
+ donel = true;
+ if (ql.Count == 0)
+ {
+ if (qr.Count > 0)
+ {
+ observer.OnNext(false);
+ observer.OnCompleted();
+ }
+ else if (doner)
+ {
+ observer.OnNext(true);
+ observer.OnCompleted();
+ }
+ }
+ }
+ });
+
+ var subscription2 = second.Subscribe(
+ x =>
+ {
+ lock (gate)
+ {
+ if (ql.Count > 0)
+ {
+ var equal = false;
+ var v = ql.Dequeue();
+ try
+ {
+ equal = comparer.Equals(v, x);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+ if (!equal)
+ {
+ observer.OnNext(false);
+ observer.OnCompleted();
+ }
+ }
+ else if (donel)
+ {
+ observer.OnNext(false);
+ observer.OnCompleted();
+ }
+ else
+ qr.Enqueue(x);
+ }
+ },
+ observer.OnError,
+ () =>
+ {
+ lock (gate)
+ {
+ doner = true;
+ if (qr.Count == 0)
+ {
+ if (ql.Count > 0)
+ {
+ observer.OnNext(false);
+ observer.OnCompleted();
+ }
+ else if (donel)
+ {
+ observer.OnNext(true);
+ observer.OnCompleted();
+ }
+ }
+ }
+ });
+
+ return new CompositeDisposable(subscription1, subscription2);
+ });
+#endif
+ }
+
+ public virtual IObservable<bool> SequenceEqual<TSource>(IObservable<TSource> first, IEnumerable<TSource> second)
+ {
+#if !NO_PERF
+ return new SequenceEqual<TSource>(first, second, EqualityComparer<TSource>.Default);
+#else
+ return SequenceEqual<TSource>(first, second, EqualityComparer<TSource>.Default);
+#endif
+ }
+
+ public virtual IObservable<bool> SequenceEqual<TSource>(IObservable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
+ {
+#if !NO_PERF
+ return new SequenceEqual<TSource>(first, second, comparer);
+#else
+ return new AnonymousObservable<bool>(observer =>
+ {
+ var e = default(IEnumerator<TSource>);
+ try
+ {
+ e = second.GetEnumerator();
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return Disposable.Empty;
+ }
+
+ return new CompositeDisposable(
+ first.Subscribe(
+ value =>
+ {
+ var equal = false;
+ try
+ {
+ var hasNext = e.MoveNext();
+ if (hasNext)
+ {
+ var current = e.Current;
+ equal = comparer.Equals(value, current);
+ }
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ if (!equal)
+ {
+ observer.OnNext(false);
+ observer.OnCompleted();
+ }
+ },
+ observer.OnError,
+ () =>
+ {
+ var hasNext = false;
+
+ try
+ {
+ hasNext = e.MoveNext();
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ observer.OnNext(!hasNext);
+ observer.OnCompleted();
+ }
+ ),
+ e
+ );
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + SingleAsync +
+
+ public virtual IObservable<TSource> SingleAsync<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new SingleAsync<TSource>(source, null, true);
+#else
+ return SingleOrDefaultAsync_(source, true);
+#endif
+ }
+
+ public virtual IObservable<TSource> SingleAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new SingleAsync<TSource>(source, predicate, true);
+#else
+ return source.Where(predicate).SingleAsync();
+#endif
+ }
+
+ #endregion
+
+ #region + SingleOrDefaultAsync +
+
+ public virtual IObservable<TSource> SingleOrDefaultAsync<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new SingleAsync<TSource>(source, null, false);
+#else
+ return SingleOrDefaultAsync_(source, false);
+#endif
+ }
+
+ public virtual IObservable<TSource> SingleOrDefaultAsync<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new SingleAsync<TSource>(source, predicate, false);
+#else
+ return source.Where(predicate).SingleOrDefaultAsync();
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TSource> SingleOrDefaultAsync_<TSource>(IObservable<TSource> source, bool throwOnEmpty)
+ {
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var value = default(TSource);
+ var seenValue = false;
+
+ return source.Subscribe(
+ x =>
+ {
+ if (seenValue)
+ {
+ observer.OnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_ELEMENT));
+ }
+ else
+ {
+ value = x;
+ seenValue = true;
+ }
+ },
+ observer.OnError,
+ () =>
+ {
+ if (throwOnEmpty && !seenValue)
+ {
+ observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ }
+ else
+ {
+ observer.OnNext(value);
+ observer.OnCompleted();
+ }
+ }
+ );
+ });
+ }
+#endif
+
+ #endregion
+
+ #region + Sum +
+
+ public virtual IObservable<double> Sum(IObservable<double> source)
+ {
+#if !NO_PERF
+ return new SumDouble(source);
+#else
+ return source.Aggregate(0.0, (prev, curr) => prev + curr);
+#endif
+ }
+
+ public virtual IObservable<float> Sum(IObservable<float> source)
+ {
+#if !NO_PERF
+ return new SumSingle(source);
+#else
+ return source.Aggregate(0f, (prev, curr) => prev + curr);
+#endif
+ }
+
+ public virtual IObservable<decimal> Sum(IObservable<decimal> source)
+ {
+#if !NO_PERF
+ return new SumDecimal(source);
+#else
+ return source.Aggregate(0M, (prev, curr) => prev + curr);
+#endif
+ }
+
+ public virtual IObservable<int> Sum(IObservable<int> source)
+ {
+#if !NO_PERF
+ return new SumInt32(source);
+#else
+ return source.Aggregate(0, (prev, curr) => checked(prev + curr));
+#endif
+ }
+
+ public virtual IObservable<long> Sum(IObservable<long> source)
+ {
+#if !NO_PERF
+ return new SumInt64(source);
+#else
+ return source.Aggregate(0L, (prev, curr) => checked(prev + curr));
+#endif
+ }
+
+ public virtual IObservable<double?> Sum(IObservable<double?> source)
+ {
+#if !NO_PERF
+ return new SumDoubleNullable(source);
+#else
+ return source.Aggregate(0.0, (prev, curr) => prev + curr.GetValueOrDefault()).Select(x => (double?)x);
+#endif
+ }
+
+ public virtual IObservable<float?> Sum(IObservable<float?> source)
+ {
+#if !NO_PERF
+ return new SumSingleNullable(source);
+#else
+ return source.Aggregate(0f, (prev, curr) => prev + curr.GetValueOrDefault()).Select(x => (float?)x);
+#endif
+ }
+
+ public virtual IObservable<decimal?> Sum(IObservable<decimal?> source)
+ {
+#if !NO_PERF
+ return new SumDecimalNullable(source);
+#else
+ return source.Aggregate(0M, (prev, curr) => prev + curr.GetValueOrDefault()).Select(x => (decimal?)x);
+#endif
+ }
+
+ public virtual IObservable<int?> Sum(IObservable<int?> source)
+ {
+#if !NO_PERF
+ return new SumInt32Nullable(source);
+#else
+ return source.Aggregate(0, (prev, curr) => checked(prev + curr.GetValueOrDefault())).Select(x => (int?)x);
+#endif
+ }
+
+ public virtual IObservable<long?> Sum(IObservable<long?> source)
+ {
+#if !NO_PERF
+ return new SumInt64Nullable(source);
+#else
+ return source.Aggregate(0L, (prev, curr) => checked(prev + curr.GetValueOrDefault())).Select(x => (long?)x);
+#endif
+ }
+
+ public virtual IObservable<double> Sum<TSource>(IObservable<TSource> source, Func<TSource, double> selector)
+ {
+ return Sum(Select(source, selector));
+ }
+
+ public virtual IObservable<float> Sum<TSource>(IObservable<TSource> source, Func<TSource, float> selector)
+ {
+ return Sum(Select(source, selector));
+ }
+
+ public virtual IObservable<decimal> Sum<TSource>(IObservable<TSource> source, Func<TSource, decimal> selector)
+ {
+ return Sum(Select(source, selector));
+ }
+
+ public virtual IObservable<int> Sum<TSource>(IObservable<TSource> source, Func<TSource, int> selector)
+ {
+ return Sum(Select(source, selector));
+ }
+
+ public virtual IObservable<long> Sum<TSource>(IObservable<TSource> source, Func<TSource, long> selector)
+ {
+ return Sum(Select(source, selector));
+ }
+
+ public virtual IObservable<double?> Sum<TSource>(IObservable<TSource> source, Func<TSource, double?> selector)
+ {
+ return Sum(Select(source, selector));
+ }
+
+ public virtual IObservable<float?> Sum<TSource>(IObservable<TSource> source, Func<TSource, float?> selector)
+ {
+ return Sum(Select(source, selector));
+ }
+
+ public virtual IObservable<decimal?> Sum<TSource>(IObservable<TSource> source, Func<TSource, decimal?> selector)
+ {
+ return Sum(Select(source, selector));
+ }
+
+ public virtual IObservable<int?> Sum<TSource>(IObservable<TSource> source, Func<TSource, int?> selector)
+ {
+ return Sum(Select(source, selector));
+ }
+
+ public virtual IObservable<long?> Sum<TSource>(IObservable<TSource> source, Func<TSource, long?> selector)
+ {
+ return Sum(Select(source, selector));
+ }
+
+ #endregion
+
+ #region + ToArray +
+
+ public virtual IObservable<TSource[]> ToArray<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new ToArray<TSource>(source);
+#else
+ return source.ToList().Select(xs => xs.ToArray());
+#endif
+ }
+
+ #endregion
+
+ #region + ToDictionary +
+
+ public virtual IObservable<IDictionary<TKey, TElement>> ToDictionary<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+ {
+#if !NO_PERF
+ return new ToDictionary<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
+#else
+ return source.Aggregate((IDictionary<TKey, TElement>)new Dictionary<TKey, TElement>(comparer), (dict, x) =>
+ {
+ dict.Add(keySelector(x), elementSelector(x));
+ return dict;
+ });
+#endif
+ }
+
+ public virtual IObservable<IDictionary<TKey, TElement>> ToDictionary<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
+ {
+#if !NO_PERF
+ return new ToDictionary<TSource, TKey, TElement>(source, keySelector, elementSelector, EqualityComparer<TKey>.Default);
+#else
+ return source.ToDictionary(keySelector, elementSelector, EqualityComparer<TKey>.Default);
+#endif
+ }
+
+ public virtual IObservable<IDictionary<TKey, TSource>> ToDictionary<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+#if !NO_PERF
+ return new ToDictionary<TSource, TKey, TSource>(source, keySelector, x => x, comparer);
+#else
+ return source.ToDictionary(keySelector, x => x, comparer);
+#endif
+ }
+
+ public virtual IObservable<IDictionary<TKey, TSource>> ToDictionary<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+#if !NO_PERF
+ return new ToDictionary<TSource, TKey, TSource>(source, keySelector, x => x, EqualityComparer<TKey>.Default);
+#else
+ return source.ToDictionary(keySelector, x => x, EqualityComparer<TKey>.Default);
+#endif
+ }
+
+ #endregion
+
+ #region + ToList +
+
+ public virtual IObservable<IList<TSource>> ToList<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new ToList<TSource>(source);
+#else
+ return source.Aggregate((IList<TSource>)new List<TSource>(), (list, x) =>
+ {
+ list.Add(x);
+ return list;
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + ToLookup +
+
+ public virtual IObservable<ILookup<TKey, TElement>> ToLookup<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+ {
+#if !NO_PERF
+ return new ToLookup<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
+#else
+ return source.Aggregate(new Lookup<TKey, TElement>(comparer), (lookup, x) =>
+ {
+ lookup.Add(keySelector(x), elementSelector(x));
+ return lookup;
+ }).Select(xs => (ILookup<TKey, TElement>)xs);
+#endif
+ }
+
+ public virtual IObservable<ILookup<TKey, TSource>> ToLookup<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+#if !NO_PERF
+ return new ToLookup<TSource, TKey, TSource>(source, keySelector, x => x, comparer);
+#else
+ return source.ToLookup(keySelector, x => x, comparer);
+#endif
+ }
+
+ public virtual IObservable<ILookup<TKey, TElement>> ToLookup<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
+ {
+#if !NO_PERF
+ return new ToLookup<TSource, TKey, TElement>(source, keySelector, elementSelector, EqualityComparer<TKey>.Default);
+#else
+ return source.ToLookup(keySelector, elementSelector, EqualityComparer<TKey>.Default);
+#endif
+ }
+
+ public virtual IObservable<ILookup<TKey, TSource>> ToLookup<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+#if !NO_PERF
+ return new ToLookup<TSource, TKey, TSource>(source, keySelector, x => x, EqualityComparer<TKey>.Default);
+#else
+ return source.ToLookup(keySelector, x => x, EqualityComparer<TKey>.Default);
+#endif
+ }
+
+ #endregion
+
+ #region |> Helpers <|
+
+#if NO_PERF
+ private static T? NullableMin<T>(T? x, T? y)
+ where T : struct, IComparable<T>
+ {
+ if (!x.HasValue)
+ return y;
+ if (!y.HasValue)
+ return x;
+ if (x.Value.CompareTo(y.Value) <= 0)
+ return x;
+ return y;
+ }
+
+ private static T? NullableMax<T>(T? x, T? y)
+ where T : struct, IComparable<T>
+ {
+ if (!x.HasValue)
+ return y;
+ if (!y.HasValue)
+ return x;
+ if (x.Value.CompareTo(y.Value) >= 0)
+ return x;
+ return y;
+ }
+
+ private static IObservable<IList<TSource>> ExtremaBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
+ {
+ return new AnonymousObservable<IList<TSource>>(observer =>
+ {
+ var hasValue = false;
+ var lastKey = default(TKey);
+ var list = new List<TSource>();
+ return source.Subscribe(
+ x =>
+ {
+ var key = default(TKey);
+ try
+ {
+ key = keySelector(x);
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+ var comparison = 0;
+
+ if (!hasValue)
+ {
+ hasValue = true;
+ lastKey = key;
+ }
+ else
+ {
+ try
+ {
+ comparison = comparer.Compare(key, lastKey);
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+ }
+ if (comparison > 0)
+ {
+ lastKey = key;
+ list.Clear();
+ }
+ if (comparison >= 0)
+ {
+ list.Add(x);
+ }
+ },
+ observer.OnError,
+ () =>
+ {
+ observer.OnNext(list);
+ observer.OnCompleted();
+ }
+ );
+ });
+ }
+#endif
+
+ #endregion
+ }
+
+ #region |> Helper types <|
+
+#if NO_PERF
+ static class AggregateExtensions
+ {
+ public static IObservable<TSource> Final<TSource>(this IObservable<TSource> source)
+ {
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var value = default(TSource);
+ var hasValue = false;
+
+ return source.Subscribe(
+ x =>
+ {
+ hasValue = true;
+ value = x;
+ },
+ observer.OnError,
+ () =>
+ {
+ if (!hasValue)
+ observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+ else
+ {
+ observer.OnNext(value);
+ observer.OnCompleted();
+ }
+ });
+ });
+ }
+ }
+
+ sealed class AnonymousComparer<T> : IComparer<T>
+ {
+ private readonly Func<T, T, int> comparer;
+
+ /// <summary>
+ /// Creates an instance of IComparer by providing a method that compares two objects.
+ /// </summary>
+ public AnonymousComparer(Func<T, T, int> comparer)
+ {
+ this.comparer = comparer;
+ }
+
+ /// <summary>
+ /// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
+ /// </summary>
+ public int Compare(T x, T y)
+ {
+ return comparer(x, y);
+ }
+ }
+#endif
+
+ #endregion
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Async.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Async.cs
new file mode 100644
index 0000000..21f36f4
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Async.cs
@@ -0,0 +1,1796 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+#if !NO_TPL
+using System.Reactive.Threading.Tasks;
+using System.Threading;
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+ internal partial class QueryLanguage
+ {
+ #region FromAsyncPattern
+
+ #region Func
+
+ public virtual Func<IObservable<TResult>> FromAsyncPattern<TResult>(Func<AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return () =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(iar =>
+ {
+ // Note: Even if the callback completes synchronously, outgoing On* calls
+ // cannot throw in user code since there can't be any subscribers
+ // to the AsyncSubject yet. Therefore, there is no need to protect
+ // against exceptions that'd be caught below and sent (incorrectly)
+ // into the Observable.Throw sequence being constructed.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, IObservable<TResult>> FromAsyncPattern<T1, TResult>(Func<T1, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return x =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, IObservable<TResult>> FromAsyncPattern<T1, T2, TResult>(Func<T1, T2, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+#if !NO_LARGEARITY
+ public virtual Func<T1, T2, T3, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, TResult>(Func<T1, T2, T3, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, TResult>(Func<T1, T2, T3, T4, T5, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a, b) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, b, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, TResult>(Func<T1, T2, T3, T4, T5, T6, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a, b, c) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, b, c, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a, b, c, d) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, b, c, d, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a, b, c, d, e) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, b, c, d, e, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a, b, c, d, e, f) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, b, c, d, e, f, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a, b, c, d, e, f, g) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, b, c, d, e, f, g, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a, b, c, d, e, f, g, h) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, b, c, d, e, f, g, h, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a, b, c, d, e, f, g, h, i) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, b, c, d, e, f, g, h, i, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a, b, c, d, e, f, g, h, i, j) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, b, c, d, e, f, g, h, i, j, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<TResult>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)
+ {
+ return (x, y, z, a, b, c, d, e, f, g, h, i, j, k) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ try
+ {
+ begin(x, y, z, a, b, c, d, e, f, g, h, i, j, k, iar =>
+ {
+ // See remark on FromAsyncPattern<TResult>.
+ TResult result;
+ try
+ {
+ result = end(iar);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ }, null);
+ }
+ catch (Exception exception)
+ {
+ return Observable.Throw<TResult>(exception, SchedulerDefaults.AsyncConversions);
+ }
+ return subject.AsObservable();
+ };
+ }
+#endif
+
+ #endregion
+
+ #region Action
+
+ public virtual Func<IObservable<Unit>> FromAsyncPattern(Func<AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, IObservable<Unit>> FromAsyncPattern<T1>(Func<T1, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, IObservable<Unit>> FromAsyncPattern<T1, T2>(Func<T1, T2, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+#if !NO_LARGEARITY
+ public virtual Func<T1, T2, T3, IObservable<Unit>> FromAsyncPattern<T1, T2, T3>(Func<T1, T2, T3, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4>(Func<T1, T2, T3, T4, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5>(Func<T1, T2, T3, T4, T5, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6>(Func<T1, T2, T3, T4, T5, T6, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7>(Func<T1, T2, T3, T4, T5, T6, T7, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8>(Func<T1, T2, T3, T4, T5, T6, T7, T8, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<Unit>> FromAsyncPattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, AsyncCallback, object, IAsyncResult> begin, Action<IAsyncResult> end)
+ {
+ return FromAsyncPattern(begin, iar =>
+ {
+ end(iar);
+ return Unit.Default;
+ });
+ }
+#endif
+
+ #endregion
+
+ #endregion
+
+ #region Start[Async]
+
+ #region Func
+
+ public virtual IObservable<TSource> Start<TSource>(Func<TSource> function)
+ {
+ return ToAsync(function)();
+ }
+
+ public virtual IObservable<TSource> Start<TSource>(Func<TSource> function, IScheduler scheduler)
+ {
+ return ToAsync(function, scheduler)();
+ }
+
+#if !NO_TPL
+ public virtual IObservable<TSource> StartAsync<TSource>(Func<Task<TSource>> functionAsync)
+ {
+ var task = default(Task<TSource>);
+ try
+ {
+ task = functionAsync();
+ }
+ catch (Exception exception)
+ {
+ return Throw<TSource>(exception);
+ }
+
+ return task.ToObservable();
+ }
+
+ public virtual IObservable<TSource> StartAsync<TSource>(Func<CancellationToken, Task<TSource>> functionAsync)
+ {
+ var cancellable = new CancellationDisposable();
+
+ var task = default(Task<TSource>);
+ try
+ {
+ task = functionAsync(cancellable.Token);
+ }
+ catch (Exception exception)
+ {
+ return Throw<TSource>(exception);
+ }
+
+ var result = task.ToObservable();
+
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ //
+ // [OK] Use of unsafe Subscribe: result is an AsyncSubject<TSource>.
+ //
+ var subscription = result.Subscribe/*Unsafe*/(observer);
+ return new CompositeDisposable(cancellable, subscription);
+ });
+ }
+#endif
+
+ #endregion
+
+ #region Action
+
+ public virtual IObservable<Unit> Start(Action action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions)();
+ }
+
+ public virtual IObservable<Unit> Start(Action action, IScheduler scheduler)
+ {
+ return ToAsync(action, scheduler)();
+ }
+
+#if !NO_TPL
+ public virtual IObservable<Unit> StartAsync(Func<Task> actionAsync)
+ {
+ var task = default(Task);
+ try
+ {
+ task = actionAsync();
+ }
+ catch (Exception exception)
+ {
+ return Throw<Unit>(exception);
+ }
+
+ return task.ToObservable();
+ }
+
+ public virtual IObservable<Unit> StartAsync(Func<CancellationToken, Task> actionAsync)
+ {
+ var cancellable = new CancellationDisposable();
+
+ var task = default(Task);
+ try
+ {
+ task = actionAsync(cancellable.Token);
+ }
+ catch (Exception exception)
+ {
+ return Throw<Unit>(exception);
+ }
+
+ var result = task.ToObservable();
+
+ return new AnonymousObservable<Unit>(observer =>
+ {
+ //
+ // [OK] Use of unsafe Subscribe: result is an AsyncSubject<TSource>.
+ //
+ var subscription = result.Subscribe/*Unsafe*/(observer);
+ return new CompositeDisposable(cancellable, subscription);
+ });
+ }
+#endif
+
+ #endregion
+
+ #endregion
+
+ #region FromAsync
+
+#if !NO_TPL
+
+ #region Func
+
+ public virtual IObservable<TResult> FromAsync<TResult>(Func<Task<TResult>> functionAsync)
+ {
+ return Defer(() => StartAsync(functionAsync));
+ }
+
+ public virtual IObservable<TResult> FromAsync<TResult>(Func<CancellationToken, Task<TResult>> functionAsync)
+ {
+ return Defer(() => StartAsync(functionAsync));
+ }
+
+ #endregion
+
+ #region Action
+
+ public virtual IObservable<Unit> FromAsync(Func<Task> actionAsync)
+ {
+ return Defer(() => StartAsync(actionAsync));
+ }
+
+ public virtual IObservable<Unit> FromAsync(Func<CancellationToken, Task> actionAsync)
+ {
+ return Defer(() => StartAsync(actionAsync));
+ }
+
+ #endregion
+
+#endif
+
+ #endregion
+
+ #region ToAsync
+
+ #region Func
+
+ public virtual Func<IObservable<TResult>> ToAsync<TResult>(Func<TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<IObservable<TResult>> ToAsync<TResult>(Func<TResult> function, IScheduler scheduler)
+ {
+ return () =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function();
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T, IObservable<TResult>> ToAsync<T, TResult>(Func<T, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T, IObservable<TResult>> ToAsync<T, TResult>(Func<T, TResult> function, IScheduler scheduler)
+ {
+ return (first) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, IObservable<TResult>> ToAsync<T1, T2, TResult>(Func<T1, T2, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, IObservable<TResult>> ToAsync<T1, T2, TResult>(Func<T1, T2, TResult> function, IScheduler scheduler)
+ {
+ return (first, second) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, IObservable<TResult>> ToAsync<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, IObservable<TResult>> ToAsync<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, IObservable<TResult>> ToAsync<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, IObservable<TResult>> ToAsync<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+#if !NO_LARGEARITY
+
+ public virtual Func<T1, T2, T3, T4, T5, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, TResult>(Func<T1, T2, T3, T4, T5, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, TResult>(Func<T1, T2, T3, T4, T5, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, TResult>(Func<T1, T2, T3, T4, T5, T6, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, TResult>(Func<T1, T2, T3, T4, T5, T6, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth, seventh);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eight) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth, seventh, eight);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eight, ninth) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth, seventh, eight, ninth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh, twelfth) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh, twelfth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh, twelfth, thirteenth) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh, twelfth, thirteenth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> function)
+ {
+ return ToAsync(function, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, IObservable<TResult>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> function, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth, sixteenth) =>
+ {
+ var subject = new AsyncSubject<TResult>();
+ scheduler.Schedule(() =>
+ {
+ var result = default(TResult);
+ try
+ {
+ result = function(first, second, third, fourth, fifth, sixth, seventh, eight, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth, sixteenth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(result);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+#endif
+
+ #endregion
+
+ #region Action
+
+ public virtual Func<IObservable<Unit>> ToAsync(Action action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<IObservable<Unit>> ToAsync(Action action, IScheduler scheduler)
+ {
+ return () =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action();
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<TSource, IObservable<Unit>> ToAsync<TSource>(Action<TSource> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<TSource, IObservable<Unit>> ToAsync<TSource>(Action<TSource> action, IScheduler scheduler)
+ {
+ return (first) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, IObservable<Unit>> ToAsync<T1, T2>(Action<T1, T2> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, IObservable<Unit>> ToAsync<T1, T2>(Action<T1, T2> action, IScheduler scheduler)
+ {
+ return (first, second) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, IObservable<Unit>> ToAsync<T1, T2, T3>(Action<T1, T2, T3> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, IObservable<Unit>> ToAsync<T1, T2, T3>(Action<T1, T2, T3> action, IScheduler scheduler)
+ {
+ return (first, second, third) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, IObservable<Unit>> ToAsync<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, IObservable<Unit>> ToAsync<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+#if !NO_LARGEARITY
+
+ public virtual Func<T1, T2, T3, T4, T5, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth, seventh);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eight) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth, seventh, eight);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eighth, ninth) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> action)
+ {
+ return ToAsync(action, SchedulerDefaults.AsyncConversions);
+ }
+
+ public virtual Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, IObservable<Unit>> ToAsync<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> action, IScheduler scheduler)
+ {
+ return (first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth, sixteenth) =>
+ {
+ var subject = new AsyncSubject<Unit>();
+ scheduler.Schedule(() =>
+ {
+ try
+ {
+ action(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth, sixteenth);
+ }
+ catch (Exception exception)
+ {
+ subject.OnError(exception);
+ return;
+ }
+ subject.OnNext(Unit.Default);
+ subject.OnCompleted();
+ });
+ return subject.AsObservable();
+ };
+ }
+
+#endif
+
+ #endregion
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Awaiter.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Awaiter.cs
new file mode 100644
index 0000000..6a48bf0
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Awaiter.cs
@@ -0,0 +1,64 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if HAS_AWAIT
+using System.Threading;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq
+{
+ internal partial class QueryLanguage
+ {
+ public virtual AsyncSubject<TSource> GetAwaiter<TSource>(IObservable<TSource> source)
+ {
+ var s = new AsyncSubject<TSource>();
+ source.SubscribeSafe(s);
+ return s;
+ }
+
+ public virtual AsyncSubject<TSource> GetAwaiter<TSource>(IConnectableObservable<TSource> source)
+ {
+ var s = new AsyncSubject<TSource>();
+ source.SubscribeSafe(s);
+ source.Connect();
+ return s;
+ }
+
+ public virtual AsyncSubject<TSource> RunAsync<TSource>(IObservable<TSource> source, CancellationToken cancellationToken)
+ {
+ var s = new AsyncSubject<TSource>();
+
+ var cancel = new Action(() => s.OnError(new OperationCanceledException()));
+ if (cancellationToken.IsCancellationRequested)
+ {
+ cancel();
+ return s;
+ }
+
+ var d = source.SubscribeSafe(s);
+ cancellationToken.Register(d.Dispose);
+ cancellationToken.Register(cancel);
+
+ return s;
+ }
+
+ public virtual AsyncSubject<TSource> RunAsync<TSource>(IConnectableObservable<TSource> source, CancellationToken cancellationToken)
+ {
+ var s = new AsyncSubject<TSource>();
+
+ var cancel = new Action(() => s.OnError(new OperationCanceledException()));
+ if (cancellationToken.IsCancellationRequested)
+ {
+ cancel();
+ return s;
+ }
+
+ var d = new CompositeDisposable(source.SubscribeSafe(s), source.Connect());
+ cancellationToken.Register(d.Dispose);
+ cancellationToken.Register(cancel);
+
+ return s;
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Binding.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Binding.cs
new file mode 100644
index 0000000..d9a96ba
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Binding.cs
@@ -0,0 +1,158 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq
+{
+ using Observαble;
+
+ internal partial class QueryLanguage
+ {
+ #region + Multicast +
+
+ public virtual IConnectableObservable<TResult> Multicast<TSource, TResult>(IObservable<TSource> source, ISubject<TSource, TResult> subject)
+ {
+ return new ConnectableObservable<TSource, TResult>(source, subject);
+ }
+
+ public virtual IObservable<TResult> Multicast<TSource, TIntermediate, TResult>(IObservable<TSource> source, Func<ISubject<TSource, TIntermediate>> subjectSelector, Func<IObservable<TIntermediate>, IObservable<TResult>> selector)
+ {
+ return new Multicast<TSource, TIntermediate, TResult>(source, subjectSelector, selector);
+ }
+
+ #endregion
+
+ #region + Publish +
+
+ public virtual IConnectableObservable<TSource> Publish<TSource>(IObservable<TSource> source)
+ {
+ return source.Multicast(new Subject<TSource>());
+ }
+
+ public virtual IObservable<TResult> Publish<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector)
+ {
+ return source.Multicast(() => new Subject<TSource>(), selector);
+ }
+
+ public virtual IConnectableObservable<TSource> Publish<TSource>(IObservable<TSource> source, TSource initialValue)
+ {
+ return source.Multicast(new BehaviorSubject<TSource>(initialValue));
+ }
+
+ public virtual IObservable<TResult> Publish<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TSource initialValue)
+ {
+ return source.Multicast(() => new BehaviorSubject<TSource>(initialValue), selector);
+ }
+
+ #endregion
+
+ #region + PublishLast +
+
+ public virtual IConnectableObservable<TSource> PublishLast<TSource>(IObservable<TSource> source)
+ {
+ return source.Multicast(new AsyncSubject<TSource>());
+ }
+
+ public virtual IObservable<TResult> PublishLast<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector)
+ {
+ return source.Multicast(() => new AsyncSubject<TSource>(), selector);
+ }
+
+ #endregion
+
+ #region + RefCount +
+
+ public virtual IObservable<TSource> RefCount<TSource>(IConnectableObservable<TSource> source)
+ {
+ return new RefCount<TSource>(source);
+ }
+
+ #endregion
+
+ #region + Replay +
+
+ public virtual IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source)
+ {
+ return source.Multicast(new ReplaySubject<TSource>());
+ }
+
+ public virtual IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, IScheduler scheduler)
+ {
+ return source.Multicast(new ReplaySubject<TSource>(scheduler));
+ }
+
+ public virtual IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector)
+ {
+ return source.Multicast(() => new ReplaySubject<TSource>(), selector);
+ }
+
+ public virtual IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, IScheduler scheduler)
+ {
+ return source.Multicast(() => new ReplaySubject<TSource>(scheduler), selector);
+ }
+
+ public virtual IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, TimeSpan window)
+ {
+ return source.Multicast(new ReplaySubject<TSource>(window));
+ }
+
+ public virtual IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TimeSpan window)
+ {
+ return source.Multicast(() => new ReplaySubject<TSource>(window), selector);
+ }
+
+ public virtual IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, TimeSpan window, IScheduler scheduler)
+ {
+ return source.Multicast(new ReplaySubject<TSource>(window, scheduler));
+ }
+
+ public virtual IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TimeSpan window, IScheduler scheduler)
+ {
+ return source.Multicast(() => new ReplaySubject<TSource>(window, scheduler), selector);
+ }
+
+ public virtual IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, int bufferSize, IScheduler scheduler)
+ {
+ return source.Multicast(new ReplaySubject<TSource>(bufferSize, scheduler));
+ }
+
+ public virtual IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, IScheduler scheduler)
+ {
+ return source.Multicast(() => new ReplaySubject<TSource>(bufferSize, scheduler), selector);
+ }
+
+ public virtual IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, int bufferSize)
+ {
+ return source.Multicast(new ReplaySubject<TSource>(bufferSize));
+ }
+
+ public virtual IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize)
+ {
+ return source.Multicast(() => new ReplaySubject<TSource>(bufferSize), selector);
+ }
+
+ public virtual IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, int bufferSize, TimeSpan window)
+ {
+ return source.Multicast(new ReplaySubject<TSource>(bufferSize, window));
+ }
+
+ public virtual IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, TimeSpan window)
+ {
+ return source.Multicast(() => new ReplaySubject<TSource>(bufferSize, window), selector);
+ }
+
+ public virtual IConnectableObservable<TSource> Replay<TSource>(IObservable<TSource> source, int bufferSize, TimeSpan window, IScheduler scheduler)
+ {
+ return source.Multicast(new ReplaySubject<TSource>(bufferSize, window, scheduler));
+ }
+
+ public virtual IObservable<TResult> Replay<TSource, TResult>(IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, TimeSpan window, IScheduler scheduler)
+ {
+ return source.Multicast(() => new ReplaySubject<TSource>(bufferSize, window, scheduler), selector);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Blocking.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Blocking.cs
new file mode 100644
index 0000000..2b37006
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Blocking.cs
@@ -0,0 +1,464 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+using System.Reactive.Disposables;
+
+#if NO_SEMAPHORE
+using System.Reactive.Threading;
+#endif
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ internal partial class QueryLanguage
+ {
+ #region - Chunkify -
+
+ public virtual IEnumerable<IList<TSource>> Chunkify<TSource>(IObservable<TSource> source)
+ {
+ return source.Collect<TSource, IList<TSource>>(() => new List<TSource>(), (lst, x) => { lst.Add(x); return lst; }, _ => new List<TSource>());
+ }
+
+ #endregion
+
+ #region + Collect +
+
+ public virtual IEnumerable<TResult> Collect<TSource, TResult>(IObservable<TSource> source, Func<TResult> newCollector, Func<TResult, TSource, TResult> merge)
+ {
+ return Collect_<TSource, TResult>(source, newCollector, merge, _ => newCollector());
+ }
+
+ public virtual IEnumerable<TResult> Collect<TSource, TResult>(IObservable<TSource> source, Func<TResult> getInitialCollector, Func<TResult, TSource, TResult> merge, Func<TResult, TResult> getNewCollector)
+ {
+ return Collect_<TSource, TResult>(source, getInitialCollector, merge, getNewCollector);
+ }
+
+ private static IEnumerable<TResult> Collect_<TSource, TResult>(IObservable<TSource> source, Func<TResult> getInitialCollector, Func<TResult, TSource, TResult> merge, Func<TResult, TResult> getNewCollector)
+ {
+#if !NO_PERF
+ return new Collect<TSource, TResult>(source, getInitialCollector, merge, getNewCollector);
+#else
+ return new AnonymousEnumerable<TResult>(() =>
+ {
+ var c = getInitialCollector();
+ var f = default(Notification<TSource>);
+ var o = new object();
+ var done = false;
+ return PushToPull<TSource, TResult>(
+ source,
+ x =>
+ {
+ lock (o)
+ {
+ if (x.HasValue)
+ {
+ try
+ {
+ c = merge(c, x.Value);
+ }
+ catch (Exception ex)
+ {
+ f = Notification.CreateOnError<TSource>(ex);
+ }
+ }
+ else
+ f = x;
+ }
+ },
+ () =>
+ {
+ if (f != null)
+ {
+ if (f.Kind == NotificationKind.OnError)
+ {
+ return Notification.CreateOnError<TResult>(f.Exception);
+ }
+ else
+ {
+ if (done)
+ return Notification.CreateOnCompleted<TResult>();
+ else
+ done = true;
+ }
+ }
+
+ var l = default(TResult);
+ lock (o)
+ {
+ l = c;
+ c = getNewCollector(c);
+ }
+
+ return Notification.CreateOnNext(l);
+ }
+ );
+ });
+#endif
+ }
+
+ #endregion
+
+ #region First
+
+ public virtual TSource First<TSource>(IObservable<TSource> source)
+ {
+ return FirstOrDefaultInternal(source, true);
+ }
+
+ public virtual TSource First<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ return First(Where(source, predicate));
+ }
+
+ #endregion
+
+ #region FirstOrDefault
+
+ public virtual TSource FirstOrDefault<TSource>(IObservable<TSource> source)
+ {
+ return FirstOrDefaultInternal(source, false);
+ }
+
+ public virtual TSource FirstOrDefault<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ return FirstOrDefault(Where(source, predicate));
+ }
+
+ private static TSource FirstOrDefaultInternal<TSource>(IObservable<TSource> source, bool throwOnEmpty)
+ {
+ var value = default(TSource);
+ var seenValue = false;
+ var ex = default(Exception);
+ var evt = new ManualResetEvent(false);
+
+ //
+ // [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)
+ {
+ value = v;
+ }
+ seenValue = true;
+ evt.Set();
+ },
+ e =>
+ {
+ ex = e;
+ evt.Set();
+ },
+ () =>
+ {
+ evt.Set();
+ })))
+ {
+ evt.WaitOne();
+ }
+
+ ex.ThrowIfNotNull();
+
+ if (throwOnEmpty && !seenValue)
+ throw new InvalidOperationException(Strings_Linq.NO_ELEMENTS);
+
+ return value;
+ }
+
+ #endregion
+
+ #region + ForEach +
+
+ public virtual void ForEach<TSource>(IObservable<TSource> source, Action<TSource> onNext)
+ {
+#if !NO_PERF
+ var evt = new ManualResetEvent(false);
+ var sink = new ForEach<TSource>._(onNext, () => evt.Set());
+
+ using (source.SubscribeSafe(sink))
+ {
+ evt.WaitOne();
+ }
+
+ sink.Error.ThrowIfNotNull();
+#else
+ ForEach_(source, onNext);
+#endif
+ }
+
+ public virtual void ForEach<TSource>(IObservable<TSource> source, Action<TSource, int> onNext)
+ {
+#if !NO_PERF
+ var evt = new ManualResetEvent(false);
+ var sink = new ForEach<TSource>.τ(onNext, () => evt.Set());
+
+ using (source.SubscribeSafe(sink))
+ {
+ evt.WaitOne();
+ }
+
+ sink.Error.ThrowIfNotNull();
+#else
+ var i = 0;
+ ForEach_(source, x => onNext(x, checked(i++)));
+#endif
+ }
+
+#if NO_PERF
+ private static void ForEach_<TSource>(IObservable<TSource> source, Action<TSource> onNext)
+ {
+ var exception = default(Exception);
+
+ var evt = new ManualResetEvent(false);
+ using (source.Subscribe(
+ x =>
+ {
+ try
+ {
+ onNext(x);
+ }
+ catch (Exception ex)
+ {
+ exception = ex;
+ evt.Set();
+ }
+ },
+ ex =>
+ {
+ exception = ex;
+ evt.Set();
+ },
+ () => evt.Set()
+ ))
+ {
+ evt.WaitOne();
+ }
+
+ if (exception != null)
+ exception.Throw();
+ }
+#endif
+
+ #endregion
+
+ #region + GetEnumerator +
+
+ public virtual IEnumerator<TSource> GetEnumerator<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF && !NO_CDS
+ var e = new GetEnumerator<TSource>();
+ return e.Run(source);
+#else
+ var q = new Queue<Notification<TSource>>();
+ var s = new Semaphore(0, int.MaxValue);
+ return PushToPull(
+ source,
+ x =>
+ {
+ lock (q)
+ q.Enqueue(x);
+ s.Release();
+ },
+ () =>
+ {
+ s.WaitOne();
+ lock (q)
+ return q.Dequeue();
+ });
+#endif
+ }
+
+ #endregion
+
+ #region Last
+
+ public virtual TSource Last<TSource>(IObservable<TSource> source)
+ {
+ return LastOrDefaultInternal(source, true);
+ }
+
+ public virtual TSource Last<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ return Last(Where(source, predicate));
+ }
+
+ #endregion
+
+ #region LastOrDefault
+
+ public virtual TSource LastOrDefault<TSource>(IObservable<TSource> source)
+ {
+ return LastOrDefaultInternal(source, false);
+ }
+
+ public virtual TSource LastOrDefault<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ return LastOrDefault(Where(source, predicate));
+ }
+
+ private static TSource LastOrDefaultInternal<TSource>(IObservable<TSource> source, bool throwOnEmpty)
+ {
+ var value = default(TSource);
+ var seenValue = false;
+ var ex = default(Exception);
+ var evt = new ManualResetEvent(false);
+
+ //
+ // [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 =>
+ {
+ seenValue = true;
+ value = v;
+ },
+ e =>
+ {
+ ex = e;
+ evt.Set();
+ },
+ () =>
+ {
+ evt.Set();
+ })))
+ {
+ evt.WaitOne();
+ }
+
+ ex.ThrowIfNotNull();
+
+ if (throwOnEmpty && !seenValue)
+ throw new InvalidOperationException(Strings_Linq.NO_ELEMENTS);
+
+ return value;
+ }
+
+ #endregion
+
+ #region + Latest +
+
+ public virtual IEnumerable<TSource> Latest<TSource>(IObservable<TSource> source)
+ {
+ return new Latest<TSource>(source);
+ }
+
+ #endregion
+
+ #region + MostRecent +
+
+ public virtual IEnumerable<TSource> MostRecent<TSource>(IObservable<TSource> source, TSource initialValue)
+ {
+ return new MostRecent<TSource>(source, initialValue);
+ }
+
+ #endregion
+
+ #region + Next +
+
+ public virtual IEnumerable<TSource> Next<TSource>(IObservable<TSource> source)
+ {
+ return new Next<TSource>(source);
+ }
+
+ #endregion
+
+ #region Single
+
+ public virtual TSource Single<TSource>(IObservable<TSource> source)
+ {
+ return SingleOrDefaultInternal(source, true);
+ }
+
+ public virtual TSource Single<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ return Single(Where(source, predicate));
+ }
+
+ #endregion
+
+ #region SingleOrDefault
+
+ public virtual TSource SingleOrDefault<TSource>(IObservable<TSource> source)
+ {
+ return SingleOrDefaultInternal(source, false);
+ }
+
+ public virtual TSource SingleOrDefault<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ return SingleOrDefault(Where(source, predicate));
+ }
+
+ private static TSource SingleOrDefaultInternal<TSource>(IObservable<TSource> source, bool throwOnEmpty)
+ {
+ var value = default(TSource);
+ var seenValue = false;
+ var ex = default(Exception);
+ var evt = new ManualResetEvent(false);
+
+ //
+ // [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)
+ {
+ ex = new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_ELEMENT);
+ evt.Set();
+ }
+
+ value = v;
+ seenValue = true;
+ },
+ e =>
+ {
+ ex = e;
+ evt.Set();
+ },
+ () =>
+ {
+ evt.Set();
+ })))
+ {
+ evt.WaitOne();
+ }
+
+ ex.ThrowIfNotNull();
+
+ if (throwOnEmpty && !seenValue)
+ throw new InvalidOperationException(Strings_Linq.NO_ELEMENTS);
+
+ return value;
+ }
+
+ #endregion
+
+ #region Wait
+
+ public virtual TSource Wait<TSource>(IObservable<TSource> source)
+ {
+ return LastOrDefaultInternal(source, true);
+ }
+
+ #endregion
+
+ #region |> Helpers <|
+
+#if NO_CDS || NO_PERF
+ private static IEnumerator<TResult> PushToPull<TSource, TResult>(IObservable<TSource> source, Action<Notification<TSource>> push, Func<Notification<TResult>> pull)
+ {
+ var subscription = new SingleAssignmentDisposable();
+ var adapter = new PushPullAdapter<TSource, TResult>(push, pull, subscription.Dispose);
+ subscription.Disposable = source.SubscribeSafe(adapter);
+ return adapter;
+ }
+#endif
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Concurrency.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Concurrency.cs
new file mode 100644
index 0000000..58408b2
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Concurrency.cs
@@ -0,0 +1,61 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Threading;
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ internal partial class QueryLanguage
+ {
+ #region + ObserveOn +
+
+ public virtual IObservable<TSource> ObserveOn<TSource>(IObservable<TSource> source, IScheduler scheduler)
+ {
+ return Synchronization.ObserveOn<TSource>(source, scheduler);
+ }
+
+#if !NO_SYNCCTX
+ public virtual IObservable<TSource> ObserveOn<TSource>(IObservable<TSource> source, SynchronizationContext context)
+ {
+ return Synchronization.ObserveOn<TSource>(source, context);
+ }
+#endif
+
+ #endregion
+
+ #region + SubscribeOn +
+
+ public virtual IObservable<TSource> SubscribeOn<TSource>(IObservable<TSource> source, IScheduler scheduler)
+ {
+ return Synchronization.SubscribeOn<TSource>(source, scheduler);
+ }
+
+#if !NO_SYNCCTX
+ public virtual IObservable<TSource> SubscribeOn<TSource>(IObservable<TSource> source, SynchronizationContext context)
+ {
+ return Synchronization.SubscribeOn<TSource>(source, context);
+ }
+#endif
+
+ #endregion
+
+ #region + Synchronize +
+
+ public virtual IObservable<TSource> Synchronize<TSource>(IObservable<TSource> source)
+ {
+ return Synchronization.Synchronize(source);
+ }
+
+ public virtual IObservable<TSource> Synchronize<TSource>(IObservable<TSource> source, object gate)
+ {
+ return Synchronization.Synchronize(source, gate);
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Conversions.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Conversions.cs
new file mode 100644
index 0000000..c75b379
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Conversions.cs
@@ -0,0 +1,159 @@
+
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ internal partial class QueryLanguage
+ {
+ #region + Subscribe +
+
+ public virtual IDisposable Subscribe<TSource>(IEnumerable<TSource> source, IObserver<TSource> observer)
+ {
+ return Subscribe_<TSource>(source, observer, SchedulerDefaults.Iteration);
+ }
+
+ public virtual IDisposable Subscribe<TSource>(IEnumerable<TSource> source, IObserver<TSource> observer, IScheduler scheduler)
+ {
+ return Subscribe_<TSource>(source, observer, scheduler);
+ }
+
+ private static IDisposable Subscribe_<TSource>(IEnumerable<TSource> source, IObserver<TSource> observer, IScheduler scheduler)
+ {
+#if !NO_PERF
+ //
+ // [OK] Use of unsafe Subscribe: we're calling into a known producer implementation.
+ //
+ return new ToObservable<TSource>(source, scheduler).Subscribe/*Unsafe*/(observer);
+#else
+ var e = source.GetEnumerator();
+ var flag = new BooleanDisposable();
+
+ scheduler.Schedule(self =>
+ {
+ var hasNext = false;
+ var ex = default(Exception);
+ var current = default(TSource);
+
+ if (flag.IsDisposed)
+ {
+ e.Dispose();
+ return;
+ }
+
+ try
+ {
+ hasNext = e.MoveNext();
+ if (hasNext)
+ current = e.Current;
+ }
+ catch (Exception exception)
+ {
+ ex = exception;
+ }
+
+ if (!hasNext || ex != null)
+ {
+ e.Dispose();
+ }
+
+ if (ex != null)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ if (!hasNext)
+ {
+ observer.OnCompleted();
+ return;
+ }
+
+ observer.OnNext(current);
+ self();
+ });
+
+ return flag;
+#endif
+ }
+
+ #endregion
+
+ #region + ToEnumerable +
+
+ public virtual IEnumerable<TSource> ToEnumerable<TSource>(IObservable<TSource> source)
+ {
+ return new AnonymousEnumerable<TSource>(() => source.GetEnumerator());
+ }
+
+ #endregion
+
+ #region ToEvent
+
+ public virtual IEventSource<Unit> ToEvent(IObservable<Unit> source)
+ {
+ return new EventSource<Unit>(source, (h, _) => h(Unit.Default));
+ }
+
+ public virtual IEventSource<TSource> ToEvent<TSource>(IObservable<TSource> source)
+ {
+ return new EventSource<TSource>(source, (h, value) => h(value));
+ }
+
+ #endregion
+
+ #region ToEventPattern
+
+ public virtual IEventPatternSource<TEventArgs> ToEventPattern<TEventArgs>(IObservable<EventPattern<TEventArgs>> source)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ return new EventPatternSource<TEventArgs>(
+#if !NO_VARIANCE
+ source,
+#else
+ source.Select(x => (EventPattern<object, TEventArgs>)x),
+#endif
+ (h, evt) => h(evt.Sender, evt.EventArgs)
+ );
+ }
+
+ #endregion
+
+ #region + ToObservable +
+
+ public virtual IObservable<TSource> ToObservable<TSource>(IEnumerable<TSource> source)
+ {
+#if !NO_PERF
+ return new ToObservable<TSource>(source, SchedulerDefaults.Iteration);
+#else
+ return ToObservable_(source, SchedulerDefaults.Iteration);
+#endif
+ }
+
+ public virtual IObservable<TSource> ToObservable<TSource>(IEnumerable<TSource> source, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new ToObservable<TSource>(source, scheduler);
+#else
+ return ToObservable_(source, scheduler);
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TSource> ToObservable_<TSource>(IEnumerable<TSource> source, IScheduler scheduler)
+ {
+ return new AnonymousObservable<TSource>(observer => source.Subscribe(observer, scheduler));
+ }
+#endif
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Creation.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Creation.cs
new file mode 100644
index 0000000..4aa25b2
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Creation.cs
@@ -0,0 +1,462 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Threading;
+using System.Linq;
+
+#if !NO_TPL
+using System.Reactive.Threading.Tasks;
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ internal partial class QueryLanguage
+ {
+ #region - Create -
+
+ public virtual IObservable<TSource> Create<TSource>(Func<IObserver<TSource>, IDisposable> subscribe)
+ {
+ return new AnonymousObservable<TSource>(subscribe);
+ }
+
+ public virtual IObservable<TSource> Create<TSource>(Func<IObserver<TSource>, Action> subscribe)
+ {
+ return new AnonymousObservable<TSource>(o =>
+ {
+ var a = subscribe(o);
+ return a != null ? Disposable.Create(a) : Disposable.Empty;
+ });
+ }
+
+ #endregion
+
+ #region - CreateAsync -
+
+#if !NO_TPL
+ public virtual IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task> subscribeAsync)
+ {
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var cancellable = new CancellationDisposable();
+
+ var taskObservable = subscribeAsync(observer, cancellable.Token).ToObservable();
+ var taskCompletionObserver = new AnonymousObserver<Unit>(Stubs<Unit>.Ignore, observer.OnError, observer.OnCompleted);
+ var subscription = taskObservable.Subscribe(taskCompletionObserver);
+
+ return new CompositeDisposable(cancellable, subscription);
+ });
+ }
+
+ public virtual IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task> subscribeAsync)
+ {
+ return Create<TResult>((observer, token) => subscribeAsync(observer));
+ }
+
+ public virtual IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task<IDisposable>> subscribeAsync)
+ {
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var subscription = new SingleAssignmentDisposable();
+ var cancellable = new CancellationDisposable();
+
+ var taskObservable = subscribeAsync(observer, cancellable.Token).ToObservable();
+ var taskCompletionObserver = new AnonymousObserver<IDisposable>(d => subscription.Disposable = d ?? Disposable.Empty, observer.OnError, Stubs.Nop);
+
+ //
+ // We don't cancel the subscription below *ever* and want to make sure the returned resource gets disposed eventually.
+ // Notice because we're using the AnonymousObservable<T> type, we get auto-detach behavior for free.
+ //
+ taskObservable.Subscribe(taskCompletionObserver);
+
+ return new CompositeDisposable(cancellable, subscription);
+ });
+ }
+
+ public virtual IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task<IDisposable>> subscribeAsync)
+ {
+ return Create<TResult>((observer, token) => subscribeAsync(observer));
+ }
+
+ public virtual IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task<Action>> subscribeAsync)
+ {
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var subscription = new SingleAssignmentDisposable();
+ var cancellable = new CancellationDisposable();
+
+ var taskObservable = subscribeAsync(observer, cancellable.Token).ToObservable();
+ var taskCompletionObserver = new AnonymousObserver<Action>(a => subscription.Disposable = a != null ? Disposable.Create(a) : Disposable.Empty, observer.OnError, Stubs.Nop);
+
+ //
+ // We don't cancel the subscription below *ever* and want to make sure the returned resource eventually gets disposed.
+ // Notice because we're using the AnonymousObservable<T> type, we get auto-detach behavior for free.
+ //
+ taskObservable.Subscribe(taskCompletionObserver);
+
+ return new CompositeDisposable(cancellable, subscription);
+ });
+ }
+
+ public virtual IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task<Action>> subscribeAsync)
+ {
+ return Create<TResult>((observer, token) => subscribeAsync(observer));
+ }
+#endif
+
+ #endregion
+
+ #region + Defer +
+
+ public virtual IObservable<TValue> Defer<TValue>(Func<IObservable<TValue>> observableFactory)
+ {
+#if !NO_PERF
+ return new Defer<TValue>(observableFactory);
+#else
+ return new AnonymousObservable<TValue>(observer =>
+ {
+ IObservable<TValue> result;
+ try
+ {
+ result = observableFactory();
+ }
+ catch (Exception exception)
+ {
+ return Throw<TValue>(exception).Subscribe(observer);
+ }
+
+ return result.Subscribe(observer);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + DeferAsync +
+
+#if !NO_TPL
+ public virtual IObservable<TValue> Defer<TValue>(Func<Task<IObservable<TValue>>> observableFactoryAsync)
+ {
+ return Defer(() => StartAsync(observableFactoryAsync).Merge());
+ }
+
+ public virtual IObservable<TValue> Defer<TValue>(Func<CancellationToken, Task<IObservable<TValue>>> observableFactoryAsync)
+ {
+ return Defer(() => StartAsync(observableFactoryAsync).Merge());
+ }
+#endif
+
+ #endregion
+
+ #region + Empty +
+
+ public virtual IObservable<TResult> Empty<TResult>()
+ {
+#if !NO_PERF
+ return new Empty<TResult>(SchedulerDefaults.ConstantTimeOperations);
+#else
+ return Empty_<TResult>(SchedulerDefaults.ConstantTimeOperations);
+#endif
+ }
+
+ public virtual IObservable<TResult> Empty<TResult>(IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Empty<TResult>(scheduler);
+#else
+ return Empty_<TResult>(scheduler);
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TResult> Empty_<TResult>(IScheduler scheduler)
+ {
+ return new AnonymousObservable<TResult>(observer => scheduler.Schedule(observer.OnCompleted));
+ }
+#endif
+
+ #endregion
+
+ #region + Generate +
+
+ public virtual IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector)
+ {
+#if !NO_PERF
+ return new Generate<TState, TResult>(initialState, condition, iterate, resultSelector, SchedulerDefaults.Iteration);
+#else
+ return Generate_<TState, TResult>(initialState, condition, iterate, resultSelector, SchedulerDefaults.Iteration);
+#endif
+ }
+
+ public virtual IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Generate<TState, TResult>(initialState, condition, iterate, resultSelector, scheduler);
+#else
+ return Generate_<TState, TResult>(initialState, condition, iterate, resultSelector, scheduler);
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TResult> Generate_<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, IScheduler scheduler)
+ {
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var state = initialState;
+ var first = true;
+ return scheduler.Schedule(self =>
+ {
+ var hasResult = false;
+ var result = default(TResult);
+ try
+ {
+ if (first)
+ first = false;
+ else
+ state = iterate(state);
+ hasResult = condition(state);
+ if (hasResult)
+ result = resultSelector(state);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ if (hasResult)
+ {
+ observer.OnNext(result);
+ self();
+ }
+ else
+ observer.OnCompleted();
+ });
+ });
+ }
+#endif
+
+ #endregion
+
+ #region + Never +
+
+ public virtual IObservable<TResult> Never<TResult>()
+ {
+#if !NO_PERF
+ return new Never<TResult>();
+#else
+ return new AnonymousObservable<TResult>(observer => Disposable.Empty);
+#endif
+ }
+
+ #endregion
+
+ #region + Range +
+
+ public virtual IObservable<int> Range(int start, int count)
+ {
+ return Range_(start, count, SchedulerDefaults.Iteration);
+ }
+
+ public virtual IObservable<int> Range(int start, int count, IScheduler scheduler)
+ {
+ return Range_(start, count, scheduler);
+ }
+
+ private static IObservable<int> Range_(int start, int count, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Range(start, count, scheduler);
+#else
+ return new AnonymousObservable<int>(observer =>
+ {
+ return scheduler.Schedule(0, (i, self) =>
+ {
+ if (i < count)
+ {
+ observer.OnNext(start + i);
+ self(i + 1);
+ }
+ else
+ observer.OnCompleted();
+ });
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Repeat +
+
+ public virtual IObservable<TResult> Repeat<TResult>(TResult value)
+ {
+#if !NO_PERF
+ return new Repeat<TResult>(value, null, SchedulerDefaults.Iteration);
+#else
+ return Repeat_(value, SchedulerDefaults.Iteration);
+#endif
+ }
+
+ public virtual IObservable<TResult> Repeat<TResult>(TResult value, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Repeat<TResult>(value, null, scheduler);
+#else
+ return Repeat_<TResult>(value, scheduler);
+#endif
+ }
+
+#if NO_PERF
+ private IObservable<TResult> Repeat_<TResult>(TResult value, IScheduler scheduler)
+ {
+ return Return(value, scheduler).Repeat();
+ }
+#endif
+
+ public virtual IObservable<TResult> Repeat<TResult>(TResult value, int repeatCount)
+ {
+#if !NO_PERF
+ return new Repeat<TResult>(value, repeatCount, SchedulerDefaults.Iteration);
+#else
+ return Repeat_(value, repeatCount, SchedulerDefaults.Iteration);
+#endif
+ }
+
+ public virtual IObservable<TResult> Repeat<TResult>(TResult value, int repeatCount, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Repeat<TResult>(value, repeatCount, scheduler);
+#else
+ return Repeat_(value, repeatCount, scheduler);
+#endif
+ }
+
+#if NO_PERF
+ private IObservable<TResult> Repeat_<TResult>(TResult value, int repeatCount, IScheduler scheduler)
+ {
+ return Return(value, scheduler).Repeat(repeatCount);
+ }
+#endif
+
+ #endregion
+
+ #region + Return +
+
+ public virtual IObservable<TResult> Return<TResult>(TResult value)
+ {
+#if !NO_PERF
+ return new Return<TResult>(value, SchedulerDefaults.ConstantTimeOperations);
+#else
+ return Return_<TResult>(value, SchedulerDefaults.ConstantTimeOperations);
+#endif
+ }
+
+ public virtual IObservable<TResult> Return<TResult>(TResult value, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Return<TResult>(value, scheduler);
+#else
+ return Return_<TResult>(value, scheduler);
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TResult> Return_<TResult>(TResult value, IScheduler scheduler)
+ {
+ return new AnonymousObservable<TResult>(observer =>
+ scheduler.Schedule(() =>
+ {
+ observer.OnNext(value);
+ observer.OnCompleted();
+ })
+ );
+ }
+#endif
+
+ #endregion
+
+ #region + Throw +
+
+ public virtual IObservable<TResult> Throw<TResult>(Exception exception)
+ {
+#if !NO_PERF
+ return new Throw<TResult>(exception, SchedulerDefaults.ConstantTimeOperations);
+#else
+ return Throw_<TResult>(exception, SchedulerDefaults.ConstantTimeOperations);
+#endif
+ }
+
+ public virtual IObservable<TResult> Throw<TResult>(Exception exception, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Throw<TResult>(exception, scheduler);
+#else
+ return Throw_<TResult>(exception, scheduler);
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TResult> Throw_<TResult>(Exception exception, IScheduler scheduler)
+ {
+ return new AnonymousObservable<TResult>(observer => scheduler.Schedule(() => observer.OnError(exception)));
+ }
+#endif
+
+ #endregion
+
+ #region + Using +
+
+ public virtual IObservable<TSource> Using<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IObservable<TSource>> observableFactory) where TResource : IDisposable
+ {
+#if !NO_PERF
+ return new Using<TSource, TResource>(resourceFactory, observableFactory);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var source = default(IObservable<TSource>);
+ var disposable = Disposable.Empty;
+ try
+ {
+ var resource = resourceFactory();
+ if (resource != null)
+ disposable = resource;
+ source = observableFactory(resource);
+ }
+ catch (Exception exception)
+ {
+ return new CompositeDisposable(Throw<TSource>(exception).Subscribe(observer), disposable);
+ }
+
+ return new CompositeDisposable(source.Subscribe(observer), disposable);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region - UsingAsync -
+
+#if !NO_TPL
+
+ public virtual IObservable<TSource> Using<TSource, TResource>(Func<CancellationToken, Task<TResource>> resourceFactoryAsync, Func<TResource, CancellationToken, Task<IObservable<TSource>>> observableFactoryAsync) where TResource : IDisposable
+ {
+ return Observable.FromAsync<TResource>(resourceFactoryAsync)
+ .SelectMany(resource =>
+ Observable.Using<TSource, TResource>(
+ () => resource,
+ resource_ => Observable.FromAsync<IObservable<TSource>>(ct => observableFactoryAsync(resource_, ct)).Merge()
+ )
+ );
+ }
+
+#endif
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Events.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Events.cs
new file mode 100644
index 0000000..3b9f2bf
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Events.cs
@@ -0,0 +1,653 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Globalization;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reflection;
+using System.Threading;
+
+#if HAS_WINRT
+using System.Runtime.InteropServices.WindowsRuntime;
+#endif
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ //
+ // BREAKING CHANGE v2 > v1.x - FromEvent[Pattern] now has an implicit SubscribeOn and Publish operation.
+ //
+ // See FromEvent.cs for more information.
+ //
+ internal partial class QueryLanguage
+ {
+ #region + FromEventPattern +
+
+ #region Strongly typed
+
+ #region Action<EventHandler>
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<EventArgs>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler)
+ {
+ return FromEventPattern_(addHandler, removeHandler, GetSchedulerForCurrentContext());
+ }
+
+ public virtual IObservable<EventPattern<EventArgs>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IScheduler scheduler)
+ {
+ return FromEventPattern_(addHandler, removeHandler, scheduler);
+ }
+#else
+ public virtual IObservable<EventPattern<object>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler)
+ {
+ return FromEventPattern_(addHandler, removeHandler, GetSchedulerForCurrentContext());
+ }
+
+ public virtual IObservable<EventPattern<object>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IScheduler scheduler)
+ {
+ return FromEventPattern_(addHandler, removeHandler, scheduler);
+ }
+#endif
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<EventArgs>> FromEventPattern_(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new FromEventPattern.τ<EventHandler, EventArgs>(e => new EventHandler(e), addHandler, removeHandler, scheduler);
+#else
+ var res = Observable.FromEventPattern<EventHandler, EventArgs>(e => new EventHandler(e), addHandler, removeHandler);
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+#else
+ private static IObservable<EventPattern<object>> FromEventPattern_(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new FromEventPattern.τ<EventHandler, object>(e => new EventHandler(e), addHandler, removeHandler, scheduler);
+#else
+ var res = Observable.FromEventPattern<EventHandler, object>(e => new EventHandler(e), addHandler, removeHandler);
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+#endif
+
+ #endregion
+
+ #endregion
+
+ #region Action<TDelegate>
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
+#endif
+ {
+ return FromEventPattern_<TDelegate, TEventArgs>(addHandler, removeHandler, GetSchedulerForCurrentContext());
+ }
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<TDelegate, TEventArgs>(addHandler, removeHandler, scheduler);
+ }
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<TEventArgs>> FromEventPattern_<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ private static IObservable<EventPattern<TEventArgs>> FromEventPattern_<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+#endif
+ {
+#if !NO_PERF
+ return new FromEventPattern.τ<TDelegate, TEventArgs>(addHandler, removeHandler, scheduler);
+#else
+ var res = new AnonymousObservable<EventPattern<TEventArgs>>(observer =>
+ {
+ Action<object, TEventArgs> handler = (sender, eventArgs) => observer.OnNext(new EventPattern<TEventArgs>(sender, eventArgs));
+ var d = ReflectionUtils.CreateDelegate<TDelegate>(handler, typeof(Action<object, TEventArgs>).GetMethod("Invoke"));
+ addHandler(d);
+ return Disposable.Create(() => removeHandler(d));
+ });
+
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+
+ #endregion
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
+#endif
+ {
+ return FromEventPattern_<TDelegate, TEventArgs>(conversion, addHandler, removeHandler, GetSchedulerForCurrentContext());
+ }
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<TDelegate, TEventArgs>(conversion, addHandler, removeHandler, scheduler);
+ }
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<TEventArgs>> FromEventPattern_<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ private static IObservable<EventPattern<TEventArgs>> FromEventPattern_<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+#endif
+ {
+#if !NO_PERF
+ return new FromEventPattern.τ<TDelegate, TEventArgs>(conversion, addHandler, removeHandler, scheduler);
+#else
+ var res = new AnonymousObservable<EventPattern<TEventArgs>>(observer =>
+ {
+ var handler = conversion((sender, eventArgs) => observer.OnNext(new EventPattern<TEventArgs>(sender, eventArgs)));
+ addHandler(handler);
+ return Disposable.Create(() => removeHandler(handler));
+ });
+
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+
+ #endregion
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
+#endif
+ {
+ return FromEventPattern_<TDelegate, TSender, TEventArgs>(addHandler, removeHandler, GetSchedulerForCurrentContext());
+ }
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<TDelegate, TSender, TEventArgs>(addHandler, removeHandler, scheduler);
+ }
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern_<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ private static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern_<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+#endif
+ {
+#if !NO_PERF
+ return new FromEventPattern.τ<TDelegate, TSender, TEventArgs>(addHandler, removeHandler, scheduler);
+#else
+ var res = new AnonymousObservable<EventPattern<TSender, TEventArgs>>(observer =>
+ {
+ Action<TSender, TEventArgs> handler = (sender, eventArgs) => observer.OnNext(new EventPattern<TSender, TEventArgs>(sender, eventArgs));
+ var d = ReflectionUtils.CreateDelegate<TDelegate>(handler, typeof(Action<TSender, TEventArgs>).GetMethod("Invoke"));
+ addHandler(d);
+ return Disposable.Create(() => removeHandler(d));
+ });
+
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Action<EventHandler<TEventArgs>>
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler)
+#endif
+ {
+ return FromEventPattern_<TEventArgs>(addHandler, removeHandler, GetSchedulerForCurrentContext());
+ }
+
+ #if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<TEventArgs>(addHandler, removeHandler, scheduler);
+ }
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<TEventArgs>> FromEventPattern_<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ private static IObservable<EventPattern<TEventArgs>> FromEventPattern_<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler, IScheduler scheduler)
+#endif
+ {
+#if !NO_PERF
+ return new FromEventPattern.τ<EventHandler<TEventArgs>, TEventArgs>(handler => handler, addHandler, removeHandler, scheduler);
+#else
+ var res = Observable.FromEventPattern<EventHandler<TEventArgs>, TEventArgs>(handler => handler, addHandler, removeHandler);
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region Reflection
+
+ #region Instance events
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<EventArgs>> FromEventPattern(object target, string eventName)
+ {
+ return FromEventPattern_(target, eventName, GetSchedulerForCurrentContext());
+ }
+
+ public virtual IObservable<EventPattern<EventArgs>> FromEventPattern(object target, string eventName, IScheduler scheduler)
+ {
+ return FromEventPattern_(target, eventName, scheduler);
+ }
+#else
+ public virtual IObservable<EventPattern<object>> FromEventPattern(object target, string eventName)
+ {
+ return FromEventPattern_(target, eventName, GetSchedulerForCurrentContext());
+ }
+
+ public virtual IObservable<EventPattern<object>> FromEventPattern(object target, string eventName, IScheduler scheduler)
+ {
+ return FromEventPattern_(target, eventName, scheduler);
+ }
+#endif
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<EventArgs>> FromEventPattern_(object target, string eventName, IScheduler scheduler)
+ {
+ return FromEventPattern_<object, EventArgs, EventPattern<EventArgs>>(target.GetType(), target, eventName, (sender, args) => new EventPattern<EventArgs>(sender, args), scheduler);
+ }
+#else
+ private static IObservable<EventPattern<object>> FromEventPattern_(object target, string eventName, IScheduler scheduler)
+ {
+ return FromEventPattern_<object, object, EventPattern<object>>(target.GetType(), target, eventName, (sender, args) => new EventPattern<object>(sender, args), scheduler);
+ }
+#endif
+
+ #endregion
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName)
+#endif
+ {
+ return FromEventPattern_<TEventArgs>(target, eventName, GetSchedulerForCurrentContext());
+ }
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(object target, string eventName, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<TEventArgs>(target, eventName, scheduler);
+ }
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<TEventArgs>> FromEventPattern_<TEventArgs>(object target, string eventName, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ private static IObservable<EventPattern<TEventArgs>> FromEventPattern_<TEventArgs>(object target, string eventName, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<object, TEventArgs, EventPattern<TEventArgs>>(target.GetType(), target, eventName, (sender, args) => new EventPattern<TEventArgs>(sender, args), scheduler);
+ }
+
+ #endregion
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName)
+#endif
+ {
+ return FromEventPattern_<TSender, TEventArgs>(target, eventName, GetSchedulerForCurrentContext());
+ }
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(object target, string eventName, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<TSender, TEventArgs>(target, eventName, scheduler);
+ }
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern_<TSender, TEventArgs>(object target, string eventName, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ private static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern_<TSender, TEventArgs>(object target, string eventName, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<TSender, TEventArgs, EventPattern<TSender, TEventArgs>>(target.GetType(), target, eventName, (sender, args) => new EventPattern<TSender, TEventArgs>(sender, args), scheduler);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Static events
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<EventArgs>> FromEventPattern(Type type, string eventName)
+ {
+ return FromEventPattern_(type, eventName, GetSchedulerForCurrentContext());
+ }
+
+ public virtual IObservable<EventPattern<EventArgs>> FromEventPattern(Type type, string eventName, IScheduler scheduler)
+ {
+ return FromEventPattern_(type, eventName, scheduler);
+ }
+#else
+ public virtual IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName)
+ {
+ return FromEventPattern_(type, eventName, GetSchedulerForCurrentContext());
+ }
+
+ public virtual IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName, IScheduler scheduler)
+ {
+ return FromEventPattern_(type, eventName, scheduler);
+ }
+#endif
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<EventArgs>> FromEventPattern_(Type type, string eventName, IScheduler scheduler)
+ {
+ return FromEventPattern_<object, EventArgs, EventPattern<EventArgs>>(type, null, eventName, (sender, args) => new EventPattern<EventArgs>(sender, args), scheduler);
+ }
+#else
+ private static IObservable<EventPattern<object>> FromEventPattern_(Type type, string eventName, IScheduler scheduler)
+ {
+ return FromEventPattern_<object, object, EventPattern<object>>(type, null, eventName, (sender, args) => new EventPattern<object>(sender, args), scheduler);
+ }
+#endif
+
+ #endregion
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName)
+#endif
+ {
+ return FromEventPattern_<TEventArgs>(type, eventName, GetSchedulerForCurrentContext());
+ }
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TEventArgs>> FromEventPattern<TEventArgs>(Type type, string eventName, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<TEventArgs>(type, eventName, scheduler);
+ }
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<TEventArgs>> FromEventPattern_<TEventArgs>(Type type, string eventName, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ private static IObservable<EventPattern<TEventArgs>> FromEventPattern_<TEventArgs>(Type type, string eventName, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<object, TEventArgs, EventPattern<TEventArgs>>(type, null, eventName, (sender, args) => new EventPattern<TEventArgs>(sender, args), scheduler);
+ }
+
+ #endregion
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName)
+#endif
+ {
+ return FromEventPattern_<TSender, TEventArgs>(type, eventName, GetSchedulerForCurrentContext());
+ }
+
+#if !NO_EVENTARGS_CONSTRAINT
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ public virtual IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TSender, TEventArgs>(Type type, string eventName, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<TSender, TEventArgs>(type, eventName, scheduler);
+ }
+
+ #region Implementation
+
+#if !NO_EVENTARGS_CONSTRAINT
+ private static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern_<TSender, TEventArgs>(Type type, string eventName, IScheduler scheduler) where TEventArgs : EventArgs
+#else
+ private static IObservable<EventPattern<TSender, TEventArgs>> FromEventPattern_<TSender, TEventArgs>(Type type, string eventName, IScheduler scheduler)
+#endif
+ {
+ return FromEventPattern_<TSender, TEventArgs, EventPattern<TSender, TEventArgs>>(type, null, eventName, (sender, args) => new EventPattern<TSender, TEventArgs>(sender, args), scheduler);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Helper methods
+
+ private static IObservable<TResult> FromEventPattern_<TSender, TEventArgs, TResult>(Type targetType, object target, string eventName, Func<TSender, TEventArgs, TResult> getResult, IScheduler scheduler)
+#if !NO_EVENTARGS_CONSTRAINT
+ where TEventArgs : EventArgs
+#endif
+ {
+ var addMethod = default(MethodInfo);
+ var removeMethod = default(MethodInfo);
+ var delegateType = default(Type);
+ var isWinRT = default(bool);
+ ReflectionUtils.GetEventMethods<TSender, TEventArgs>(targetType, target, eventName, out addMethod, out removeMethod, out delegateType, out isWinRT);
+
+#if HAS_WINRT
+ if (isWinRT)
+ {
+#if !NO_PERF
+ return new FromEventPattern.ρ<TSender, TEventArgs, TResult>(target, delegateType, addMethod, removeMethod, getResult, true, scheduler);
+#else
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ Action<TSender, TEventArgs> handler = (sender, eventArgs) => observer.OnNext(getResult(sender, eventArgs));
+ var d = ReflectionUtils.CreateDelegate(delegateType, handler, typeof(Action<TSender, TEventArgs>).GetMethod("Invoke"));
+ var token = addMethod.Invoke(target, new object[] { d });
+ return Disposable.Create(() => removeMethod.Invoke(target, new object[] { token }));
+ });
+#endif
+ }
+#endif
+
+#if !NO_PERF
+ return new FromEventPattern.ρ<TSender, TEventArgs, TResult>(target, delegateType, addMethod, removeMethod, getResult, false, scheduler);
+#else
+ var res = new AnonymousObservable<TResult>(observer =>
+ {
+ Action<TSender, TEventArgs> handler = (sender, eventArgs) => observer.OnNext(getResult(sender, eventArgs));
+ var d = ReflectionUtils.CreateDelegate(delegateType, handler, typeof(Action<TSender, TEventArgs>).GetMethod("Invoke"));
+ addMethod.Invoke(target, new object[] { d });
+ return Disposable.Create(() => removeMethod.Invoke(target, new object[] { d }));
+ });
+
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region FromEvent
+
+ public virtual IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Func<Action<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
+ {
+ return FromEvent_<TDelegate, TEventArgs>(conversion, addHandler, removeHandler, GetSchedulerForCurrentContext());
+ }
+
+ public virtual IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Func<Action<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ {
+ return FromEvent_<TDelegate, TEventArgs>(conversion, addHandler, removeHandler, scheduler);
+ }
+
+ #region Implementation
+
+ private static IObservable<TEventArgs> FromEvent_<TDelegate, TEventArgs>(Func<Action<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new FromEvent<TDelegate, TEventArgs>(conversion, addHandler, removeHandler, scheduler);
+#else
+ var res = new AnonymousObservable<TEventArgs>(observer =>
+ {
+ var handler = conversion(observer.OnNext);
+ addHandler(handler);
+ return Disposable.Create(() => removeHandler(handler));
+ });
+
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+
+ #endregion
+
+ public virtual IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
+ {
+ return FromEvent_<TDelegate, TEventArgs>(addHandler, removeHandler, GetSchedulerForCurrentContext());
+ }
+
+ public virtual IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ {
+ return FromEvent_<TDelegate, TEventArgs>(addHandler, removeHandler, scheduler);
+ }
+
+ #region Implementation
+
+ private static IObservable<TEventArgs> FromEvent_<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new FromEvent<TDelegate, TEventArgs>(addHandler, removeHandler, scheduler);
+#else
+ var res = new AnonymousObservable<TEventArgs>(observer =>
+ {
+ Action<TEventArgs> handler = observer.OnNext;
+ var d = ReflectionUtils.CreateDelegate<TDelegate>(handler, typeof(Action<TEventArgs>).GetMethod("Invoke"));
+ addHandler(d);
+ return Disposable.Create(() => removeHandler(d));
+ });
+
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+
+ #endregion
+
+ public virtual IObservable<TEventArgs> FromEvent<TEventArgs>(Action<Action<TEventArgs>> addHandler, Action<Action<TEventArgs>> removeHandler)
+ {
+ return FromEvent_<TEventArgs>(addHandler, removeHandler, GetSchedulerForCurrentContext());
+ }
+
+ public virtual IObservable<TEventArgs> FromEvent<TEventArgs>(Action<Action<TEventArgs>> addHandler, Action<Action<TEventArgs>> removeHandler, IScheduler scheduler)
+ {
+ return FromEvent_<TEventArgs>(addHandler, removeHandler, scheduler);
+ }
+
+ #region Implementation
+
+ private static IObservable<TEventArgs> FromEvent_<TEventArgs>(Action<Action<TEventArgs>> addHandler, Action<Action<TEventArgs>> removeHandler, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new FromEvent<Action<TEventArgs>, TEventArgs>(h => h, addHandler, removeHandler, scheduler);
+#else
+ var res = Observable.FromEvent<Action<TEventArgs>, TEventArgs>(h => h, addHandler, removeHandler);
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+
+ #endregion
+
+ public virtual IObservable<Unit> FromEvent(Action<Action> addHandler, Action<Action> removeHandler)
+ {
+ return FromEvent_(addHandler, removeHandler, GetSchedulerForCurrentContext());
+ }
+
+ public virtual IObservable<Unit> FromEvent(Action<Action> addHandler, Action<Action> removeHandler, IScheduler scheduler)
+ {
+ return FromEvent_(addHandler, removeHandler, scheduler);
+ }
+
+ #region Implementation
+
+ private static IObservable<Unit> FromEvent_(Action<Action> addHandler, Action<Action> removeHandler, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new FromEvent<Action, Unit>(h => new Action(() => h(new Unit())), addHandler, removeHandler, scheduler);
+#else
+ var res = Observable.FromEvent<Action, Unit>(h => new Action(() => h(new Unit())), addHandler, removeHandler);
+ return SynchronizeEvents(res, scheduler);
+#endif
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Helpers
+
+ private static IScheduler GetSchedulerForCurrentContext()
+ {
+ var context = SynchronizationContext.Current;
+
+ if (context != null)
+ return new SynchronizationContextScheduler(context, false);
+ else
+ return SchedulerDefaults.ConstantTimeOperations;
+ }
+
+#if NO_PERF
+
+ private static IObservable<T> SynchronizeEvents<T>(IObservable<T> source, IScheduler scheduler)
+ {
+ return source.SubscribeOn(scheduler).Publish().RefCount();
+ }
+
+#endif
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Imperative.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Imperative.cs
new file mode 100644
index 0000000..ff4470b
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Imperative.cs
@@ -0,0 +1,232 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+using System.Threading;
+
+#if !NO_TPL
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ internal partial class QueryLanguage
+ {
+ #region ForEachAsync
+
+#if !NO_TPL
+ public virtual Task ForEachAsync<TSource>(IObservable<TSource> source, Action<TSource> onNext)
+ {
+ return ForEachAsync_(source, onNext, CancellationToken.None);
+ }
+
+ public virtual Task ForEachAsync<TSource>(IObservable<TSource> source, Action<TSource> onNext, CancellationToken cancellationToken)
+ {
+ return ForEachAsync_(source, onNext, cancellationToken);
+ }
+
+ public virtual Task ForEachAsync<TSource>(IObservable<TSource> source, Action<TSource, int> onNext)
+ {
+ var i = 0;
+ return ForEachAsync_(source, x => onNext(x, checked(i++)), CancellationToken.None);
+ }
+
+ public virtual Task ForEachAsync<TSource>(IObservable<TSource> source, Action<TSource, int> onNext, CancellationToken cancellationToken)
+ {
+ var i = 0;
+ return ForEachAsync_(source, x => onNext(x, checked(i++)), cancellationToken);
+ }
+
+ private static Task ForEachAsync_<TSource>(IObservable<TSource> source, Action<TSource> onNext, CancellationToken cancellationToken)
+ {
+ var tcs = new TaskCompletionSource<object>();
+ var subscription = new SingleAssignmentDisposable();
+
+ cancellationToken.Register(() => tcs.TrySetCanceled());
+ cancellationToken.Register(subscription.Dispose);
+
+ if (!cancellationToken.IsCancellationRequested)
+ {
+ // Making sure we always complete, even if disposing throws.
+ var dispose = new Action<Action>(action =>
+ {
+ try
+ {
+ subscription.Dispose();
+ }
+ catch (Exception ex)
+ {
+ tcs.TrySetException(ex);
+ return;
+ }
+
+ action();
+ });
+
+ var taskCompletionObserver = new AnonymousObserver<TSource>(
+ x =>
+ {
+ if (!subscription.IsDisposed)
+ {
+ try
+ {
+ onNext(x);
+ }
+ catch (Exception exception)
+ {
+ dispose(() => tcs.TrySetException(exception));
+ }
+ }
+ },
+ exception =>
+ {
+ dispose(() => tcs.TrySetException(exception));
+ },
+ () =>
+ {
+ dispose(() => tcs.TrySetResult(null));
+ }
+ );
+
+ //
+ // Subtle race condition: if the source completes before we reach the line below, the SingleAssigmentDisposable
+ // will already have been disposed. Upon assignment, the disposable resource being set will be disposed on the
+ // spot, which may throw an exception. (See TFS 487142)
+ //
+ try
+ {
+ //
+ // [OK] Use of unsafe Subscribe: we're catching the exception here to set the TaskCompletionSource.
+ //
+ // Notice we could use a safe subscription to route errors through OnError, but we still need the
+ // exception handling logic here for the reason explained above. We cannot afford to throw here
+ // and as a result never set the TaskCompletionSource, so we tunnel everything through here.
+ //
+ subscription.Disposable = source.Subscribe/*Unsafe*/(taskCompletionObserver);
+ }
+ catch (Exception ex)
+ {
+ tcs.TrySetException(ex);
+ }
+ }
+
+ return tcs.Task;
+ }
+#endif
+
+ #endregion
+
+ #region + Case +
+
+ public virtual IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources)
+ {
+ return Case(selector, sources, Empty<TResult>());
+ }
+
+ public virtual IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources, IScheduler scheduler)
+ {
+ return Case(selector, sources, Empty<TResult>(scheduler));
+ }
+
+ public virtual IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources, IObservable<TResult> defaultSource)
+ {
+#if !NO_PERF
+ return new Case<TValue, TResult>(selector, sources, defaultSource);
+#else
+ return Observable.Defer(() =>
+ {
+ IObservable<TResult> result;
+ if (!sources.TryGetValue(selector(), out result))
+ result = defaultSource;
+ return result;
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + DoWhile +
+
+ public virtual IObservable<TSource> DoWhile<TSource>(IObservable<TSource> source, Func<bool> condition)
+ {
+#if !NO_PERF
+ return new DoWhile<TSource>(source, condition);
+#else
+ return source.Concat(While(condition, source));
+#endif
+ }
+
+ #endregion
+
+ #region + For +
+
+ public virtual IObservable<TResult> For<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IObservable<TResult>> resultSelector)
+ {
+#if !NO_PERF
+ return new For<TSource, TResult>(source, resultSelector);
+#else
+ return ForCore(source, resultSelector).Concat();
+#endif
+ }
+
+#if NO_PERF
+ static IEnumerable<IObservable<TResult>> ForCore<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IObservable<TResult>> resultSelector)
+ {
+ foreach (var item in source)
+ yield return resultSelector(item);
+ }
+#endif
+
+ #endregion
+
+ #region + If +
+
+ public virtual IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource)
+ {
+ return If(condition, thenSource, Empty<TResult>());
+ }
+
+ public virtual IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource, IScheduler scheduler)
+ {
+ return If(condition, thenSource, Empty<TResult>(scheduler));
+ }
+
+ public virtual IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource, IObservable<TResult> elseSource)
+ {
+#if !NO_PERF
+ return new If<TResult>(condition, thenSource, elseSource);
+#else
+ return Observable.Defer(() => condition() ? thenSource : elseSource);
+#endif
+ }
+
+ #endregion
+
+ #region + While +
+
+ public virtual IObservable<TSource> While<TSource>(Func<bool> condition, IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new While<TSource>(condition, source);
+#else
+ return WhileCore(condition, source).Concat();
+#endif
+ }
+
+#if NO_PERF
+ static IEnumerable<IObservable<TSource>> WhileCore<TSource>(Func<bool> condition, IObservable<TSource> source)
+ {
+ while (condition())
+ yield return source;
+ }
+#endif
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Joins.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Joins.cs
new file mode 100644
index 0000000..a5ddf27
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Joins.cs
@@ -0,0 +1,84 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+using System.Reactive.Joins;
+
+namespace System.Reactive.Linq
+{
+ internal partial class QueryLanguage
+ {
+ #region And
+
+ public virtual Pattern<TLeft, TRight> And<TLeft, TRight>(IObservable<TLeft> left, IObservable<TRight> right)
+ {
+ return new Pattern<TLeft, TRight>(left, right);
+ }
+
+ #endregion
+
+ #region Then
+
+ public virtual Plan<TResult> Then<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector)
+ {
+ return new Pattern<TSource>(source).Then(selector);
+ }
+
+ #endregion
+
+ #region When
+
+ public virtual IObservable<TResult> When<TResult>(params Plan<TResult>[] plans)
+ {
+ return When((IEnumerable<Plan<TResult>>)plans);
+ }
+
+ public virtual IObservable<TResult> When<TResult>(IEnumerable<Plan<TResult>> plans)
+ {
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var externalSubscriptions = new Dictionary<object, IJoinObserver>();
+ var gate = new object();
+ var activePlans = new List<ActivePlan>();
+ var outObserver = Observer.Create<TResult>(observer.OnNext,
+ exception =>
+ {
+ foreach (var po in externalSubscriptions.Values)
+ {
+ po.Dispose();
+ }
+ observer.OnError(exception);
+ },
+ observer.OnCompleted);
+ try
+ {
+ foreach (var plan in plans)
+ activePlans.Add(plan.Activate(externalSubscriptions, outObserver,
+ activePlan =>
+ {
+ activePlans.Remove(activePlan);
+ if (activePlans.Count == 0)
+ outObserver.OnCompleted();
+ }));
+ }
+ catch (Exception e)
+ {
+ //
+ // [OK] Use of unsafe Subscribe: we're calling into a known producer implementation.
+ //
+ return Throw<TResult>(e).Subscribe/*Unsafe*/(observer);
+ }
+
+ var group = new CompositeDisposable(externalSubscriptions.Values.Count);
+ foreach (var joinObserver in externalSubscriptions.Values)
+ {
+ joinObserver.Subscribe(gate);
+ group.Add(joinObserver);
+ }
+ return group;
+ });
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Multiple.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Multiple.cs
new file mode 100644
index 0000000..cd23a97
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Multiple.cs
@@ -0,0 +1,1723 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+#if !NO_TPL
+using System.Reactive.Threading.Tasks;
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ internal partial class QueryLanguage
+ {
+ #region + Amb +
+
+ public virtual IObservable<TSource> Amb<TSource>(IObservable<TSource> first, IObservable<TSource> second)
+ {
+ return Amb_(first, second);
+ }
+
+ public virtual IObservable<TSource> Amb<TSource>(params IObservable<TSource>[] sources)
+ {
+ return Amb_(sources);
+ }
+
+ public virtual IObservable<TSource> Amb<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+ return Amb_(sources);
+ }
+
+ private static IObservable<TSource> Amb_<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+ return sources.Aggregate(Observable.Never<TSource>(), (previous, current) => previous.Amb(current));
+ }
+
+ private static IObservable<TSource> Amb_<TSource>(IObservable<TSource> leftSource, IObservable<TSource> rightSource)
+ {
+#if !NO_PERF
+ return new Amb<TSource>(leftSource, rightSource);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var leftSubscription = new SingleAssignmentDisposable();
+ var rightSubscription = new SingleAssignmentDisposable();
+
+ var choice = AmbState.Neither;
+
+ var gate = new object();
+
+ var left = new AmbObserver<TSource>();
+ var right = new AmbObserver<TSource>();
+
+ left.Observer = Observer.Synchronize(Observer.Create<TSource>(
+ x =>
+ {
+ if (choice == AmbState.Neither)
+ {
+ choice = AmbState.Left;
+ rightSubscription.Dispose();
+ left.Observer = observer;
+ }
+
+ if (choice == AmbState.Left)
+ observer.OnNext(x);
+ },
+ ex =>
+ {
+ if (choice == AmbState.Neither)
+ {
+ choice = AmbState.Left;
+ rightSubscription.Dispose();
+ left.Observer = observer;
+ }
+
+ if (choice == AmbState.Left)
+ observer.OnError(ex);
+ },
+ () =>
+ {
+ if (choice == AmbState.Neither)
+ {
+ choice = AmbState.Left;
+ rightSubscription.Dispose();
+ left.Observer = observer;
+ }
+
+ if (choice == AmbState.Left)
+ observer.OnCompleted();
+ }
+ ), gate);
+
+ right.Observer = Observer.Synchronize(Observer.Create<TSource>(
+ x =>
+ {
+ if (choice == AmbState.Neither)
+ {
+ choice = AmbState.Right;
+ leftSubscription.Dispose();
+ right.Observer = observer;
+ }
+
+ if (choice == AmbState.Right)
+ observer.OnNext(x);
+ },
+ ex =>
+ {
+ if (choice == AmbState.Neither)
+ {
+ choice = AmbState.Right;
+ leftSubscription.Dispose();
+ right.Observer = observer;
+ }
+
+ if (choice == AmbState.Right)
+ observer.OnError(ex);
+ },
+ () =>
+ {
+ if (choice == AmbState.Neither)
+ {
+ choice = AmbState.Right;
+ leftSubscription.Dispose();
+ right.Observer = observer;
+ }
+
+ if (choice == AmbState.Right)
+ observer.OnCompleted();
+ }
+ ), gate);
+
+ leftSubscription.Disposable = leftSource.Subscribe(left);
+ rightSubscription.Disposable = rightSource.Subscribe(right);
+
+ return new CompositeDisposable(leftSubscription, rightSubscription);
+ });
+#endif
+ }
+
+#if NO_PERF
+ class AmbObserver<TSource> : IObserver<TSource>
+ {
+ public virtual IObserver<TSource> Observer { get; set; }
+
+ public virtual void OnCompleted()
+ {
+ Observer.OnCompleted();
+ }
+
+ public virtual void OnError(Exception error)
+ {
+ Observer.OnError(error);
+ }
+
+ public virtual void OnNext(TSource value)
+ {
+ Observer.OnNext(value);
+ }
+ }
+
+ enum AmbState
+ {
+ Left,
+ Right,
+ Neither
+ }
+#endif
+
+ #endregion
+
+ #region + Buffer +
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource, TBufferClosing>(IObservable<TSource> source, Func<IObservable<TBufferClosing>> bufferClosingSelector)
+ {
+#if !NO_PERF
+ return new Buffer<TSource, TBufferClosing>(source, bufferClosingSelector);
+#else
+ return source.Window(bufferClosingSelector).SelectMany(ToList);
+#endif
+ }
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource, TBufferOpening, TBufferClosing>(IObservable<TSource> source, IObservable<TBufferOpening> bufferOpenings, Func<TBufferOpening, IObservable<TBufferClosing>> bufferClosingSelector)
+ {
+ return source.Window(bufferOpenings, bufferClosingSelector).SelectMany(ToList);
+ }
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource, TBufferBoundary>(IObservable<TSource> source, IObservable<TBufferBoundary> bufferBoundaries)
+ {
+#if !NO_PERF
+ return new Buffer<TSource, TBufferBoundary>(source, bufferBoundaries);
+#else
+ return source.Window(bufferBoundaries).SelectMany(ToList);
+#endif
+ }
+
+ #endregion
+
+ #region + Catch +
+
+ public virtual IObservable<TSource> Catch<TSource, TException>(IObservable<TSource> source, Func<TException, IObservable<TSource>> handler) where TException : Exception
+ {
+#if !NO_PERF
+ return new Catch<TSource, TException>(source, handler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var subscription = new SerialDisposable();
+
+ var d1 = new SingleAssignmentDisposable();
+ subscription.Disposable = d1;
+ d1.Disposable = source.Subscribe(observer.OnNext,
+ exception =>
+ {
+ var e = exception as TException;
+ if (e != null)
+ {
+ IObservable<TSource> result;
+ try
+ {
+ result = handler(e);
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ subscription.Disposable = d;
+ d.Disposable = result.Subscribe(observer);
+ }
+ else
+ observer.OnError(exception);
+ }, observer.OnCompleted);
+
+ return subscription;
+ });
+#endif
+ }
+
+ public virtual IObservable<TSource> Catch<TSource>(IObservable<TSource> first, IObservable<TSource> second)
+ {
+ return Catch_<TSource>(new[] { first, second });
+ }
+
+ public virtual IObservable<TSource> Catch<TSource>(params IObservable<TSource>[] sources)
+ {
+ return Catch_<TSource>(sources);
+ }
+
+ public virtual IObservable<TSource> Catch<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+ return Catch_<TSource>(sources);
+ }
+
+ private static IObservable<TSource> Catch_<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+#if !NO_PERF
+ return new Catch<TSource>(sources);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var gate = new AsyncLock();
+ var isDisposed = false;
+ var e = sources.GetEnumerator();
+ var subscription = new SerialDisposable();
+ var lastException = default(Exception);
+
+ var cancelable = SchedulerDefaults.TailRecursion.Schedule(self => gate.Wait(() =>
+ {
+ var current = default(IObservable<TSource>);
+ var hasNext = false;
+ var ex = default(Exception);
+
+ if (!isDisposed)
+ {
+ try
+ {
+ hasNext = e.MoveNext();
+ if (hasNext)
+ current = e.Current;
+ else
+ e.Dispose();
+ }
+ catch (Exception exception)
+ {
+ ex = exception;
+ e.Dispose();
+ }
+ }
+ else
+ return;
+
+ if (ex != null)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ if (!hasNext)
+ {
+ if (lastException != null)
+ observer.OnError(lastException);
+ else
+ observer.OnCompleted();
+ return;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ subscription.Disposable = d;
+ d.Disposable = current.Subscribe(observer.OnNext, exception =>
+ {
+ lastException = exception;
+ self();
+ }, observer.OnCompleted);
+ }));
+
+ return new CompositeDisposable(subscription, cancelable, Disposable.Create(() => gate.Wait(() =>
+ {
+ e.Dispose();
+ isDisposed = true;
+ })));
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + CombineLatest +
+
+ public virtual IObservable<TResult> CombineLatest<TFirst, TSecond, TResult>(IObservable<TFirst> first, IObservable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
+ {
+#if !NO_PERF
+ return new CombineLatest<TFirst, TSecond, TResult>(first, second, resultSelector);
+#else
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var hasLeft = false;
+ var hasRight = false;
+
+ var left = default(TFirst);
+ var right = default(TSecond);
+
+ var leftDone = false;
+ var rightDone = false;
+
+ var leftSubscription = new SingleAssignmentDisposable();
+ var rightSubscription = new SingleAssignmentDisposable();
+
+ var gate = new object();
+
+ leftSubscription.Disposable = first.Synchronize(gate).Subscribe(
+ l =>
+ {
+ hasLeft = true;
+ left = l;
+
+ if (hasRight)
+ {
+ var res = default(TResult);
+ try
+ {
+ res = resultSelector(left, right);
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ observer.OnNext(res);
+ }
+ else if (rightDone)
+ {
+ observer.OnCompleted();
+ return;
+ }
+ },
+ observer.OnError,
+ () =>
+ {
+ leftDone = true;
+
+ if (rightDone)
+ {
+ observer.OnCompleted();
+ return;
+ }
+ }
+ );
+
+ rightSubscription.Disposable = second.Synchronize(gate).Subscribe(
+ r =>
+ {
+ hasRight = true;
+ right = r;
+
+ if (hasLeft)
+ {
+ var res = default(TResult);
+ try
+ {
+ res = resultSelector(left, right);
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ observer.OnNext(res);
+ }
+ else if (leftDone)
+ {
+ observer.OnCompleted();
+ return;
+ }
+ },
+ observer.OnError,
+ () =>
+ {
+ rightDone = true;
+
+ if (leftDone)
+ {
+ observer.OnCompleted();
+ return;
+ }
+ }
+ );
+
+ return new CompositeDisposable(leftSubscription, rightSubscription);
+ });
+#endif
+ }
+
+#if !NO_PERF
+
+ /* The following code is generated by a tool checked in to $/.../Source/Tools/CodeGenerators. */
+
+ #region CombineLatest auto-generated code (6/10/2012 7:25:03 PM)
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, Func<TSource1, TSource2, TSource3, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TResult>(source1, source2, source3, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, Func<TSource1, TSource2, TSource3, TSource4, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TResult>(source1, source2, source3, source4, resultSelector);
+ }
+
+#if !NO_LARGEARITY
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TResult>(source1, source2, source3, source4, source5, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult>(source1, source2, source3, source4, source5, source6, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult>(source1, source2, source3, source4, source5, source6, source7, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, IObservable<TSource15> source15, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, resultSelector);
+ }
+
+ public virtual IObservable<TResult> CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, IObservable<TSource15> source15, IObservable<TSource16> source16, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult> resultSelector)
+ {
+ return new CombineLatest<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, source16, resultSelector);
+ }
+
+#endif
+
+ #endregion
+
+#endif
+
+ public virtual IObservable<TResult> CombineLatest<TSource, TResult>(IEnumerable<IObservable<TSource>> sources, Func<IList<TSource>, TResult> resultSelector)
+ {
+ return CombineLatest_<TSource, TResult>(sources, resultSelector);
+ }
+
+ public virtual IObservable<IList<TSource>> CombineLatest<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+ return CombineLatest_<TSource, IList<TSource>>(sources, res => res.ToList());
+ }
+
+ public virtual IObservable<IList<TSource>> CombineLatest<TSource>(params IObservable<TSource>[] sources)
+ {
+ return CombineLatest_<TSource, IList<TSource>>(sources, res => res.ToList());
+ }
+
+ private static IObservable<TResult> CombineLatest_<TSource, TResult>(IEnumerable<IObservable<TSource>> sources, Func<IList<TSource>, TResult> resultSelector)
+ {
+#if !NO_PERF
+ return new CombineLatest<TSource, TResult>(sources, resultSelector);
+#else
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var srcs = sources.ToArray();
+
+ var N = srcs.Length;
+
+ var hasValue = new bool[N];
+ var hasValueAll = false;
+
+ var values = new List<TSource>(N);
+ for (int i = 0; i < N; i++)
+ values.Add(default(TSource));
+
+ var isDone = new bool[N];
+
+ var next = new Action<int>(i =>
+ {
+ hasValue[i] = true;
+
+ if (hasValueAll || (hasValueAll = hasValue.All(Stubs<bool>.I)))
+ {
+ var res = default(TResult);
+ try
+ {
+ res = resultSelector(new ReadOnlyCollection<TSource>(values));
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ observer.OnNext(res);
+ }
+ else if (isDone.Where((x, j) => j != i).All(Stubs<bool>.I))
+ {
+ observer.OnCompleted();
+ return;
+ }
+ });
+
+ var done = new Action<int>(i =>
+ {
+ isDone[i] = true;
+
+ if (isDone.All(Stubs<bool>.I))
+ {
+ observer.OnCompleted();
+ return;
+ }
+ });
+
+ var subscriptions = new SingleAssignmentDisposable[N];
+
+ var gate = new object();
+
+ for (int i = 0; i < N; i++)
+ {
+ var j = i;
+ subscriptions[j] = new SingleAssignmentDisposable
+ {
+ Disposable = srcs[j].Synchronize(gate).Subscribe(
+ x =>
+ {
+ values[j] = x;
+ next(j);
+ },
+ observer.OnError,
+ () =>
+ {
+ done(j);
+ }
+ )
+ };
+ }
+
+ return new CompositeDisposable(subscriptions);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Concat +
+
+ public virtual IObservable<TSource> Concat<TSource>(IObservable<TSource> first, IObservable<TSource> second)
+ {
+ return Concat_<TSource>(new[] { first, second });
+ }
+
+ public virtual IObservable<TSource> Concat<TSource>(params IObservable<TSource>[] sources)
+ {
+ return Concat_<TSource>(sources);
+ }
+
+ public virtual IObservable<TSource> Concat<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+ return Concat_<TSource>(sources);
+ }
+
+ private static IObservable<TSource> Concat_<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+#if !NO_PERF
+ return new Concat<TSource>(sources);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var isDisposed = false;
+ var e = sources.GetEnumerator();
+ var subscription = new SerialDisposable();
+ var gate = new AsyncLock();
+
+ var cancelable = SchedulerDefaults.TailRecursion.Schedule(self => gate.Wait(() =>
+ {
+ var current = default(IObservable<TSource>);
+ var hasNext = false;
+ var ex = default(Exception);
+
+ if (!isDisposed)
+ {
+ try
+ {
+ hasNext = e.MoveNext();
+ if (hasNext)
+ current = e.Current;
+ else
+ e.Dispose();
+ }
+ catch (Exception exception)
+ {
+ ex = exception;
+ e.Dispose();
+ }
+ }
+ else
+ return;
+
+ if (ex != null)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ if (!hasNext)
+ {
+ observer.OnCompleted();
+ return;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ subscription.Disposable = d;
+ d.Disposable = current.Subscribe(observer.OnNext, observer.OnError, self);
+ }));
+
+ return new CompositeDisposable(subscription, cancelable, Disposable.Create(() => gate.Wait(() =>
+ {
+ e.Dispose();
+ isDisposed = true;
+ })));
+ });
+#endif
+ }
+
+ public virtual IObservable<TSource> Concat<TSource>(IObservable<IObservable<TSource>> sources)
+ {
+ return Concat_<TSource>(sources);
+ }
+
+#if !NO_TPL
+ public virtual IObservable<TSource> Concat<TSource>(IObservable<Task<TSource>> sources)
+ {
+ return Concat_<TSource>(Select(sources, TaskObservableExtensions.ToObservable));
+ }
+#endif
+
+ private IObservable<TSource> Concat_<TSource>(IObservable<IObservable<TSource>> sources)
+ {
+ return Merge(sources, 1);
+ }
+
+ #endregion
+
+ #region + Merge +
+
+ public virtual IObservable<TSource> Merge<TSource>(IObservable<IObservable<TSource>> sources)
+ {
+ return Merge_<TSource>(sources);
+ }
+
+#if !NO_TPL
+ public virtual IObservable<TSource> Merge<TSource>(IObservable<Task<TSource>> sources)
+ {
+ return Merge_<TSource>(Select(sources, TaskObservableExtensions.ToObservable));
+ }
+#endif
+
+ public virtual IObservable<TSource> Merge<TSource>(IObservable<IObservable<TSource>> sources, int maxConcurrent)
+ {
+ return Merge_<TSource>(sources, maxConcurrent);
+ }
+
+ public virtual IObservable<TSource> Merge<TSource>(IEnumerable<IObservable<TSource>> sources, int maxConcurrent)
+ {
+ return Merge_<TSource>(sources.ToObservable(), maxConcurrent);
+ }
+
+ public virtual IObservable<TSource> Merge<TSource>(IEnumerable<IObservable<TSource>> sources, int maxConcurrent, IScheduler scheduler)
+ {
+ return Merge_<TSource>(sources.ToObservable(scheduler), maxConcurrent);
+ }
+
+ public virtual IObservable<TSource> Merge<TSource>(IObservable<TSource> first, IObservable<TSource> second)
+ {
+ return Merge_<TSource>(new[] { first, second }.ToObservable());
+ }
+
+ public virtual IObservable<TSource> Merge<TSource>(IObservable<TSource> first, IObservable<TSource> second, IScheduler scheduler)
+ {
+ return Merge_<TSource>(new[] { first, second }.ToObservable(scheduler));
+ }
+
+ public virtual IObservable<TSource> Merge<TSource>(params IObservable<TSource>[] sources)
+ {
+ return Merge_<TSource>(sources.ToObservable());
+ }
+
+ public virtual IObservable<TSource> Merge<TSource>(IScheduler scheduler, params IObservable<TSource>[] sources)
+ {
+ return Merge_<TSource>(sources.ToObservable(scheduler));
+ }
+
+ public virtual IObservable<TSource> Merge<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+ return Merge_<TSource>(sources.ToObservable());
+ }
+
+ public virtual IObservable<TSource> Merge<TSource>(IEnumerable<IObservable<TSource>> sources, IScheduler scheduler)
+ {
+ return Merge_<TSource>(sources.ToObservable(scheduler));
+ }
+
+ private static IObservable<TSource> Merge_<TSource>(IObservable<IObservable<TSource>> sources)
+ {
+#if !NO_PERF
+ return new Merge<TSource>(sources);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var gate = new object();
+ var isStopped = false;
+ var m = new SingleAssignmentDisposable();
+ var group = new CompositeDisposable() { m };
+
+ m.Disposable = sources.Subscribe(
+ innerSource =>
+ {
+ var innerSubscription = new SingleAssignmentDisposable();
+ group.Add(innerSubscription);
+ innerSubscription.Disposable = innerSource.Subscribe(
+ x =>
+ {
+ lock (gate)
+ observer.OnNext(x);
+ },
+ exception =>
+ {
+ lock (gate)
+ observer.OnError(exception);
+ },
+ () =>
+ {
+ group.Remove(innerSubscription); // modification MUST occur before subsequent check
+ if (isStopped && group.Count == 1) // isStopped must be checked before group Count to ensure outer is not creating more groups
+ lock (gate)
+ observer.OnCompleted();
+ });
+ },
+ exception =>
+ {
+ lock (gate)
+ observer.OnError(exception);
+ },
+ () =>
+ {
+ isStopped = true; // modification MUST occur before subsequent check
+ if (group.Count == 1)
+ lock (gate)
+ observer.OnCompleted();
+ });
+
+ return group;
+ });
+#endif
+ }
+
+ private static IObservable<TSource> Merge_<TSource>(IObservable<IObservable<TSource>> sources, int maxConcurrent)
+ {
+#if !NO_PERF
+ return new Merge<TSource>(sources, maxConcurrent);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var gate = new object();
+ var q = new Queue<IObservable<TSource>>();
+ var isStopped = false;
+ var group = new CompositeDisposable();
+ var activeCount = 0;
+
+ var subscribe = default(Action<IObservable<TSource>>);
+ subscribe = xs =>
+ {
+ var subscription = new SingleAssignmentDisposable();
+ group.Add(subscription);
+ subscription.Disposable = xs.Subscribe(
+ x =>
+ {
+ lock (gate)
+ observer.OnNext(x);
+ },
+ exception =>
+ {
+ lock (gate)
+ observer.OnError(exception);
+ },
+ () =>
+ {
+ group.Remove(subscription);
+ lock (gate)
+ {
+ if (q.Count > 0)
+ {
+ var s = q.Dequeue();
+ subscribe(s);
+ }
+ else
+ {
+ activeCount--;
+ if (isStopped && activeCount == 0)
+ observer.OnCompleted();
+ }
+ }
+ });
+ };
+
+ group.Add(sources.Subscribe(
+ innerSource =>
+ {
+ lock (gate)
+ {
+ if (activeCount < maxConcurrent)
+ {
+ activeCount++;
+ subscribe(innerSource);
+ }
+ else
+ q.Enqueue(innerSource);
+ }
+ },
+ exception =>
+ {
+ lock (gate)
+ observer.OnError(exception);
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ isStopped = true;
+ if (activeCount == 0)
+ observer.OnCompleted();
+ }
+ }));
+
+ return group;
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + OnErrorResumeNext +
+
+ public virtual IObservable<TSource> OnErrorResumeNext<TSource>(IObservable<TSource> first, IObservable<TSource> second)
+ {
+ return OnErrorResumeNext_<TSource>(new[] { first, second });
+ }
+
+ public virtual IObservable<TSource> OnErrorResumeNext<TSource>(params IObservable<TSource>[] sources)
+ {
+ return OnErrorResumeNext_<TSource>(sources);
+ }
+
+ public virtual IObservable<TSource> OnErrorResumeNext<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+ return OnErrorResumeNext_<TSource>(sources);
+ }
+
+ private static IObservable<TSource> OnErrorResumeNext_<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+#if !NO_PERF
+ return new OnErrorResumeNext<TSource>(sources);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var gate = new AsyncLock();
+ var isDisposed = false;
+ var e = sources.GetEnumerator();
+ var subscription = new SerialDisposable();
+
+ var cancelable = SchedulerDefaults.TailRecursion.Schedule(self => gate.Wait(() =>
+ {
+ var current = default(IObservable<TSource>);
+ var hasNext = false;
+ var ex = default(Exception);
+
+ if (!isDisposed)
+ {
+ try
+ {
+ hasNext = e.MoveNext();
+ if (hasNext)
+ current = e.Current;
+ else
+ e.Dispose();
+ }
+ catch (Exception exception)
+ {
+ ex = exception;
+ e.Dispose();
+ }
+ }
+ else
+ return;
+
+ if (ex != null)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ if (!hasNext)
+ {
+ observer.OnCompleted();
+ return;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ subscription.Disposable = d;
+ d.Disposable = current.Subscribe(observer.OnNext, exception => self(), self);
+ }));
+
+ return new CompositeDisposable(subscription, cancelable, Disposable.Create(() => gate.Wait(() =>
+ {
+ e.Dispose();
+ isDisposed = true;
+ })));
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + SkipUntil +
+
+ public virtual IObservable<TSource> SkipUntil<TSource, TOther>(IObservable<TSource> source, IObservable<TOther> other)
+ {
+#if !NO_PERF
+ return new SkipUntil<TSource, TOther>(source, other);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var sourceSubscription = new SingleAssignmentDisposable();
+ var otherSubscription = new SingleAssignmentDisposable();
+
+ var open = false;
+
+ var gate = new object();
+
+ sourceSubscription.Disposable = source.Synchronize(gate).Subscribe(
+ x =>
+ {
+ if (open)
+ observer.OnNext(x);
+ },
+ observer.OnError, // BREAKING CHANGE - Error propagation was guarded by "other" source in v1.0.10621 (due to materialization).
+ () =>
+ {
+ if (open)
+ observer.OnCompleted();
+ }
+ );
+
+ otherSubscription.Disposable = other.Synchronize(gate).Subscribe(
+ x =>
+ {
+ open = true;
+ otherSubscription.Dispose();
+ },
+ observer.OnError
+ );
+
+ return new CompositeDisposable(sourceSubscription, otherSubscription);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Switch +
+
+ public virtual IObservable<TSource> Switch<TSource>(IObservable<IObservable<TSource>> sources)
+ {
+ return Switch_<TSource>(sources);
+ }
+
+#if !NO_TPL
+ public virtual IObservable<TSource> Switch<TSource>(IObservable<Task<TSource>> sources)
+ {
+ return Switch_<TSource>(Select(sources, TaskObservableExtensions.ToObservable));
+ }
+#endif
+
+ private IObservable<TSource> Switch_<TSource>(IObservable<IObservable<TSource>> sources)
+ {
+#if !NO_PERF
+ return new Switch<TSource>(sources);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var gate = new object();
+ var innerSubscription = new SerialDisposable();
+ var isStopped = false;
+ var latest = 0UL;
+ var hasLatest = false;
+ var subscription = sources.Subscribe(
+ innerSource =>
+ {
+ var id = default(ulong);
+ lock (gate)
+ {
+ id = unchecked(++latest);
+ hasLatest = true;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ innerSubscription.Disposable = d;
+ d.Disposable = innerSource.Subscribe(
+ x =>
+ {
+ lock (gate)
+ {
+ if (latest == id)
+ observer.OnNext(x);
+ }
+ },
+ exception =>
+ {
+ lock (gate)
+ {
+ if (latest == id)
+ observer.OnError(exception);
+ }
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ if (latest == id)
+ {
+ hasLatest = false;
+
+ if (isStopped)
+ observer.OnCompleted();
+ }
+ }
+ });
+ },
+ exception =>
+ {
+ lock (gate)
+ observer.OnError(exception);
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ isStopped = true;
+ if (!hasLatest)
+ observer.OnCompleted();
+ }
+ });
+
+ return new CompositeDisposable(subscription, innerSubscription);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + TakeUntil +
+
+ public virtual IObservable<TSource> TakeUntil<TSource, TOther>(IObservable<TSource> source, IObservable<TOther> other)
+ {
+#if !NO_PERF
+ return new TakeUntil<TSource, TOther>(source, other);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var sourceSubscription = new SingleAssignmentDisposable();
+ var otherSubscription = new SingleAssignmentDisposable();
+
+ var gate = new object();
+
+ // COMPAT - Order of Subscribe calls per v1.0.10621
+ otherSubscription.Disposable = other.Synchronize(gate).Subscribe(
+ x =>
+ {
+ observer.OnCompleted();
+ },
+ observer.OnError
+ );
+
+ sourceSubscription.Disposable = source.Synchronize(gate).Finally(otherSubscription.Dispose).Subscribe(observer);
+
+ return new CompositeDisposable(sourceSubscription, otherSubscription);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Window +
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource, TWindowClosing>(IObservable<TSource> source, Func<IObservable<TWindowClosing>> windowClosingSelector)
+ {
+#if !NO_PERF
+ return new Window<TSource, TWindowClosing>(source, windowClosingSelector);
+#else
+ return new AnonymousObservable<IObservable<TSource>>(observer =>
+ {
+ var window = new Subject<TSource>();
+ var gate = new object();
+
+ var m = new SerialDisposable();
+ var d = new CompositeDisposable(2) { m };
+ var r = new RefCountDisposable(d);
+
+ observer.OnNext(window.AddRef(r));
+ d.Add(source.SubscribeSafe(new AnonymousObserver<TSource>(
+ x =>
+ {
+ lock (gate)
+ {
+ window.OnNext(x);
+ }
+ },
+ ex =>
+ {
+ lock (gate)
+ {
+ window.OnError(ex);
+ observer.OnError(ex);
+ }
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ window.OnCompleted();
+ observer.OnCompleted();
+ }
+ })));
+
+ var l = new AsyncLock();
+
+ Action createWindowClose = null;
+ createWindowClose = () =>
+ {
+ var windowClose = default(IObservable<TWindowClosing>);
+ try
+ {
+ windowClose = windowClosingSelector();
+ }
+ catch (Exception exception)
+ {
+ lock (gate)
+ {
+ observer.OnError(exception);
+ }
+ return;
+ }
+
+ var m1 = new SingleAssignmentDisposable();
+ m.Disposable = m1;
+ m1.Disposable = windowClose.Take(1).SubscribeSafe(new AnonymousObserver<TWindowClosing>(
+ Stubs<TWindowClosing>.Ignore,
+ ex =>
+ {
+ lock (gate)
+ {
+ window.OnError(ex);
+ observer.OnError(ex);
+ }
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ window.OnCompleted();
+ window = new Subject<TSource>();
+ observer.OnNext(window.AddRef(r));
+ }
+ l.Wait(createWindowClose);
+ }));
+ };
+
+ l.Wait(createWindowClose);
+
+ return r;
+ });
+#endif
+ }
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource, TWindowOpening, TWindowClosing>(IObservable<TSource> source, IObservable<TWindowOpening> windowOpenings, Func<TWindowOpening, IObservable<TWindowClosing>> windowClosingSelector)
+ {
+ return windowOpenings.GroupJoin(source, windowClosingSelector, _ => Observable.Empty<Unit>(), (_, window) => window);
+ }
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource, TWindowBoundary>(IObservable<TSource> source, IObservable<TWindowBoundary> windowBoundaries)
+ {
+#if !NO_PERF
+ return new Window<TSource, TWindowBoundary>(source, windowBoundaries);
+#else
+ return new AnonymousObservable<IObservable<TSource>>(observer =>
+ {
+ var window = new Subject<TSource>();
+ var gate = new object();
+
+ var d = new CompositeDisposable(2);
+ var r = new RefCountDisposable(d);
+
+ observer.OnNext(window.AddRef(r));
+
+ d.Add(source.SubscribeSafe(new AnonymousObserver<TSource>(
+ x =>
+ {
+ lock (gate)
+ {
+ window.OnNext(x);
+ }
+ },
+ ex =>
+ {
+ lock (gate)
+ {
+ window.OnError(ex);
+ observer.OnError(ex);
+ }
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ window.OnCompleted();
+ observer.OnCompleted();
+ }
+ }
+ )));
+
+ d.Add(windowBoundaries.SubscribeSafe(new AnonymousObserver<TWindowBoundary>(
+ w =>
+ {
+ lock (gate)
+ {
+ window.OnCompleted();
+ window = new Subject<TSource>();
+ observer.OnNext(window.AddRef(r));
+ }
+ },
+ ex =>
+ {
+ lock (gate)
+ {
+ window.OnError(ex);
+ observer.OnError(ex);
+ }
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ window.OnCompleted();
+ observer.OnCompleted();
+ }
+ }
+ )));
+
+ return r;
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Zip +
+
+ public virtual IObservable<TResult> Zip<TFirst, TSecond, TResult>(IObservable<TFirst> first, IObservable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
+ {
+#if !NO_PERF
+ return new Zip<TFirst, TSecond, TResult>(first, second, resultSelector);
+#else
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var queueLeft = new Queue<TFirst>();
+ var queueRight = new Queue<TSecond>();
+
+ var leftDone = false;
+ var rightDone = false;
+
+ var leftSubscription = new SingleAssignmentDisposable();
+ var rightSubscription = new SingleAssignmentDisposable();
+
+ var gate = new object();
+
+ leftSubscription.Disposable = first.Synchronize(gate).Subscribe(
+ l =>
+ {
+ if (queueRight.Count > 0)
+ {
+ var r = queueRight.Dequeue();
+
+ var res = default(TResult);
+ try
+ {
+ res = resultSelector(l, r);
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ observer.OnNext(res);
+ }
+ else
+ {
+ if (rightDone)
+ {
+ observer.OnCompleted();
+ return;
+ }
+
+ queueLeft.Enqueue(l);
+ }
+ },
+ observer.OnError,
+ () =>
+ {
+ leftDone = true;
+
+ if (rightDone)
+ {
+ observer.OnCompleted();
+ return;
+ }
+ }
+ );
+
+ rightSubscription.Disposable = second.Synchronize(gate).Subscribe(
+ r =>
+ {
+ if (queueLeft.Count > 0)
+ {
+ var l = queueLeft.Dequeue();
+
+ var res = default(TResult);
+ try
+ {
+ res = resultSelector(l, r);
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ observer.OnNext(res);
+ }
+ else
+ {
+ if (leftDone)
+ {
+ observer.OnCompleted();
+ return;
+ }
+
+ queueRight.Enqueue(r);
+ }
+ },
+ observer.OnError,
+ () =>
+ {
+ rightDone = true;
+
+ if (leftDone)
+ {
+ observer.OnCompleted();
+ return;
+ }
+ }
+ );
+
+ return new CompositeDisposable(leftSubscription, rightSubscription, Disposable.Create(() => { queueLeft.Clear(); queueRight.Clear(); }));
+ });
+#endif
+ }
+
+ public virtual IObservable<TResult> Zip<TSource, TResult>(IEnumerable<IObservable<TSource>> sources, Func<IList<TSource>, TResult> resultSelector)
+ {
+ return Zip_<TSource>(sources).Select(resultSelector);
+ }
+
+ public virtual IObservable<IList<TSource>> Zip<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+ return Zip_<TSource>(sources);
+ }
+
+ public virtual IObservable<IList<TSource>> Zip<TSource>(params IObservable<TSource>[] sources)
+ {
+ return Zip_<TSource>(sources);
+ }
+
+ private static IObservable<IList<TSource>> Zip_<TSource>(IEnumerable<IObservable<TSource>> sources)
+ {
+#if !NO_PERF
+ return new Zip<TSource>(sources);
+#else
+ return new AnonymousObservable<IList<TSource>>(observer =>
+ {
+ var srcs = sources.ToArray();
+
+ var N = srcs.Length;
+
+ var queues = new Queue<TSource>[N];
+ for (int i = 0; i < N; i++)
+ queues[i] = new Queue<TSource>();
+
+ var isDone = new bool[N];
+
+ var next = new Action<int>(i =>
+ {
+ if (queues.All(q => q.Count > 0))
+ {
+ var res = queues.Select(q => q.Dequeue()).ToList();
+ observer.OnNext(res);
+ }
+ else if (isDone.Where((x, j) => j != i).All(Stubs<bool>.I))
+ {
+ observer.OnCompleted();
+ return;
+ }
+ });
+
+ var done = new Action<int>(i =>
+ {
+ isDone[i] = true;
+
+ if (isDone.All(Stubs<bool>.I))
+ {
+ observer.OnCompleted();
+ return;
+ }
+ });
+
+ var subscriptions = new SingleAssignmentDisposable[N];
+
+ var gate = new object();
+
+ for (int i = 0; i < N; i++)
+ {
+ var j = i;
+ subscriptions[j] = new SingleAssignmentDisposable
+ {
+ Disposable = srcs[j].Synchronize(gate).Subscribe(
+ x =>
+ {
+ queues[j].Enqueue(x);
+ next(j);
+ },
+ observer.OnError,
+ () =>
+ {
+ done(j);
+ }
+ )
+ };
+ }
+
+ return new CompositeDisposable(subscriptions) { Disposable.Create(() => { foreach (var q in queues) q.Clear(); }) };
+ });
+#endif
+ }
+
+#if !NO_PERF
+
+ /* The following code is generated by a tool checked in to $/.../Source/Tools/CodeGenerators. */
+
+ #region Zip auto-generated code (6/10/2012 8:15:28 PM)
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, Func<TSource1, TSource2, TSource3, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TResult>(source1, source2, source3, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, Func<TSource1, TSource2, TSource3, TSource4, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TResult>(source1, source2, source3, source4, resultSelector);
+ }
+
+#if !NO_LARGEARITY
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TResult>(source1, source2, source3, source4, source5, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult>(source1, source2, source3, source4, source5, source6, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult>(source1, source2, source3, source4, source5, source6, source7, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, IObservable<TSource15> source15, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, resultSelector);
+ }
+
+ public virtual IObservable<TResult> Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult>(IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, IObservable<TSource4> source4, IObservable<TSource5> source5, IObservable<TSource6> source6, IObservable<TSource7> source7, IObservable<TSource8> source8, IObservable<TSource9> source9, IObservable<TSource10> source10, IObservable<TSource11> source11, IObservable<TSource12> source12, IObservable<TSource13> source13, IObservable<TSource14> source14, IObservable<TSource15> source15, IObservable<TSource16> source16, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult> resultSelector)
+ {
+ return new Zip<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, source16, resultSelector);
+ }
+
+#endif
+
+ #endregion
+
+#endif
+
+ public virtual IObservable<TResult> Zip<TFirst, TSecond, TResult>(IObservable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
+ {
+#if !NO_PERF
+ return new Zip<TFirst, TSecond, TResult>(first, second, resultSelector);
+#else
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var rightEnumerator = second.GetEnumerator();
+ var leftSubscription = first.Subscribe(left =>
+ {
+ var hasNext = false;
+ try
+ {
+ hasNext = rightEnumerator.MoveNext();
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ if (hasNext)
+ {
+ var right = default(TSecond);
+ try
+ {
+ right = rightEnumerator.Current;
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+
+ TResult result;
+ try
+ {
+ result = resultSelector(left, right);
+ }
+ catch (Exception ex)
+ {
+ observer.OnError(ex);
+ return;
+ }
+ observer.OnNext(result);
+ }
+ else
+ {
+ observer.OnCompleted();
+ }
+ },
+ observer.OnError,
+ observer.OnCompleted
+ );
+
+ return new CompositeDisposable(leftSubscription, rightEnumerator);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region |> Helpers <|
+
+#if NO_PERF
+
+ private static IObservable<TResult> Combine<TLeft, TRight, TResult>(IObservable<TLeft> leftSource, IObservable<TRight> rightSource, Func<IObserver<TResult>, IDisposable, IDisposable, IObserver<Either<Notification<TLeft>, Notification<TRight>>>> combinerSelector)
+ {
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var leftSubscription = new SingleAssignmentDisposable();
+ var rightSubscription = new SingleAssignmentDisposable();
+
+ var combiner = combinerSelector(observer, leftSubscription, rightSubscription);
+ var gate = new object();
+
+ leftSubscription.Disposable = leftSource.Materialize().Select(x => Either<Notification<TLeft>, Notification<TRight>>.CreateLeft(x)).Synchronize(gate).Subscribe(combiner);
+ rightSubscription.Disposable = rightSource.Materialize().Select(x => Either<Notification<TLeft>, Notification<TRight>>.CreateRight(x)).Synchronize(gate).Subscribe(combiner);
+
+ return new CompositeDisposable(leftSubscription, rightSubscription);
+ });
+ }
+
+#endif
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Single.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Single.cs
new file mode 100644
index 0000000..09e2df4
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Single.cs
@@ -0,0 +1,661 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ internal partial class QueryLanguage
+ {
+ #region + AsObservable +
+
+ public virtual IObservable<TSource> AsObservable<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ var asObservable = source as AsObservable<TSource>;
+ if (asObservable != null)
+ return asObservable.Ω();
+
+ return new AsObservable<TSource>(source);
+#else
+ return new AnonymousObservable<TSource>(observer => source.Subscribe(observer));
+#endif
+ }
+
+ #endregion
+
+ #region + Buffer +
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, int count)
+ {
+ return Buffer_<TSource>(source, count, count);
+ }
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, int count, int skip)
+ {
+ return Buffer_<TSource>(source, count, skip);
+ }
+
+ private static IObservable<IList<TSource>> Buffer_<TSource>(IObservable<TSource> source, int count, int skip)
+ {
+#if !NO_PERF
+ return new Buffer<TSource>(source, count, skip);
+#else
+ return Window_<TSource>(source, count, skip).SelectMany(Observable.ToList).Where(list => list.Count > 0);
+#endif
+ }
+
+ #endregion
+
+ #region + Dematerialize +
+
+ public virtual IObservable<TSource> Dematerialize<TSource>(IObservable<Notification<TSource>> source)
+ {
+#if !NO_PERF
+ var materialize = source as Materialize<TSource>;
+ if (materialize != null)
+ return materialize.Dematerialize();
+
+ return new Dematerialize<TSource>(source);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ source.Subscribe(x => x.Accept(observer), observer.OnError, observer.OnCompleted));
+#endif
+ }
+
+ #endregion
+
+ #region + DistinctUntilChanged +
+
+ public virtual IObservable<TSource> DistinctUntilChanged<TSource>(IObservable<TSource> source)
+ {
+ return DistinctUntilChanged_(source, x => x, EqualityComparer<TSource>.Default);
+ }
+
+ public virtual IObservable<TSource> DistinctUntilChanged<TSource>(IObservable<TSource> source, IEqualityComparer<TSource> comparer)
+ {
+ return DistinctUntilChanged_(source, x => x, comparer);
+ }
+
+ public virtual IObservable<TSource> DistinctUntilChanged<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+ return DistinctUntilChanged_(source, keySelector, EqualityComparer<TKey>.Default);
+ }
+
+ public virtual IObservable<TSource> DistinctUntilChanged<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+ return DistinctUntilChanged_(source, keySelector, comparer);
+ }
+
+ private static IObservable<TSource> DistinctUntilChanged_<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+#if !NO_PERF
+ return new DistinctUntilChanged<TSource, TKey>(source, keySelector, comparer);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var currentKey = default(TKey);
+ var hasCurrentKey = false;
+ return source.Subscribe(
+ value =>
+ {
+ var key = default(TKey);
+ try
+ {
+ key = keySelector(value);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+ var comparerEquals = false;
+ if (hasCurrentKey)
+ {
+ try
+ {
+ comparerEquals = comparer.Equals(currentKey, key);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+ }
+ if (!hasCurrentKey || !comparerEquals)
+ {
+ hasCurrentKey = true;
+ currentKey = key;
+ observer.OnNext(value);
+ }
+ },
+ observer.OnError,
+ observer.OnCompleted);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Do +
+
+ public virtual IObservable<TSource> Do<TSource>(IObservable<TSource> source, Action<TSource> onNext)
+ {
+#if !NO_PERF
+ return Do_<TSource>(source, onNext, Stubs<Exception>.Ignore, Stubs.Nop);
+#else
+ // PERFORMANCE - Use of Select allows for operator coalescing
+ return source.Select(
+ x =>
+ {
+ onNext(x);
+ return x;
+ }
+ );
+#endif
+ }
+
+ public virtual IObservable<TSource> Do<TSource>(IObservable<TSource> source, Action<TSource> onNext, Action onCompleted)
+ {
+#if !NO_PERF
+ return Do_<TSource>(source, onNext, Stubs<Exception>.Ignore, onCompleted);
+#else
+ return new AnonymousObservable<TSource>(obs =>
+ {
+ return source.Subscribe(
+ x =>
+ {
+ try
+ {
+ onNext(x);
+ }
+ catch (Exception ex)
+ {
+ obs.OnError(ex);
+ }
+ obs.OnNext(x);
+ },
+ obs.OnError,
+ () =>
+ {
+ try
+ {
+ onCompleted();
+ }
+ catch (Exception ex)
+ {
+ obs.OnError(ex);
+ }
+ obs.OnCompleted();
+ });
+ });
+#endif
+ }
+
+ public virtual IObservable<TSource> Do<TSource>(IObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError)
+ {
+#if !NO_PERF
+ return Do_<TSource>(source, onNext, onError, Stubs.Nop);
+#else
+ return new AnonymousObservable<TSource>(obs =>
+ {
+ return source.Subscribe(
+ x =>
+ {
+ try
+ {
+ onNext(x);
+ }
+ catch (Exception ex)
+ {
+ obs.OnError(ex);
+ }
+ obs.OnNext(x);
+ },
+ ex =>
+ {
+ try
+ {
+ onError(ex);
+ }
+ catch (Exception ex2)
+ {
+ obs.OnError(ex2);
+ }
+ obs.OnError(ex);
+ },
+ obs.OnCompleted);
+ });
+#endif
+ }
+
+ public virtual IObservable<TSource> Do<TSource>(IObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted)
+ {
+ return Do_(source, onNext, onError, onCompleted);
+ }
+
+ public virtual IObservable<TSource> Do<TSource>(IObservable<TSource> source, IObserver<TSource> observer)
+ {
+ return Do_(source, observer.OnNext, observer.OnError, observer.OnCompleted);
+ }
+
+ private static IObservable<TSource> Do_<TSource>(IObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted)
+ {
+#if !NO_PERF
+ return new Do<TSource>(source, onNext, onError, onCompleted);
+#else
+ return new AnonymousObservable<TSource>(obs =>
+ {
+ return source.Subscribe(
+ x =>
+ {
+ try
+ {
+ onNext(x);
+ }
+ catch (Exception ex)
+ {
+ obs.OnError(ex);
+ }
+ obs.OnNext(x);
+ },
+ ex =>
+ {
+ try
+ {
+ onError(ex);
+ }
+ catch (Exception ex2)
+ {
+ obs.OnError(ex2);
+ }
+ obs.OnError(ex);
+ },
+ () =>
+ {
+ try
+ {
+ onCompleted();
+ }
+ catch (Exception ex)
+ {
+ obs.OnError(ex);
+ }
+ obs.OnCompleted();
+ });
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Finally +
+
+ public virtual IObservable<TSource> Finally<TSource>(IObservable<TSource> source, Action finallyAction)
+ {
+#if !NO_PERF
+ return new Finally<TSource>(source, finallyAction);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var subscription = source.Subscribe(observer);
+
+ return Disposable.Create(() =>
+ {
+ try
+ {
+ subscription.Dispose();
+ }
+ finally
+ {
+ finallyAction();
+ }
+ });
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + IgnoreElements +
+
+ public virtual IObservable<TSource> IgnoreElements<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ var ignoreElements = source as IgnoreElements<TSource>;
+ if (ignoreElements != null)
+ return ignoreElements.Ω();
+
+ return new IgnoreElements<TSource>(source);
+#else
+ return new AnonymousObservable<TSource>(observer => source.Subscribe(_ => { }, observer.OnError, observer.OnCompleted));
+#endif
+ }
+
+ #endregion
+
+ #region + Materialize +
+
+ public virtual IObservable<Notification<TSource>> Materialize<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ //
+ // NOTE: Peephole optimization of xs.Dematerialize().Materialize() should not be performed. It's possible for xs to
+ // contain multiple terminal notifications, which won't survive a Dematerialize().Materialize() chain. In case
+ // a reduction to xs.AsObservable() would be performed, those notification elements would survive.
+ //
+
+ return new Materialize<TSource>(source);
+#else
+ return new AnonymousObservable<Notification<TSource>>(observer =>
+ source.Subscribe(
+ value => observer.OnNext(Notification.CreateOnNext<TSource>(value)),
+ exception =>
+ {
+ observer.OnNext(Notification.CreateOnError<TSource>(exception));
+ observer.OnCompleted();
+ },
+ () =>
+ {
+ observer.OnNext(Notification.CreateOnCompleted<TSource>());
+ observer.OnCompleted();
+ }));
+#endif
+ }
+
+ #endregion
+
+ #region - Repeat -
+
+ public virtual IObservable<TSource> Repeat<TSource>(IObservable<TSource> source)
+ {
+ return RepeatInfinite(source).Concat();
+ }
+
+ private static IEnumerable<T> RepeatInfinite<T>(T value)
+ {
+ while (true)
+ yield return value;
+ }
+
+ public virtual IObservable<TSource> Repeat<TSource>(IObservable<TSource> source, int repeatCount)
+ {
+ return Enumerable.Repeat(source, repeatCount).Concat();
+ }
+
+ #endregion
+
+ #region - Retry -
+
+ public virtual IObservable<TSource> Retry<TSource>(IObservable<TSource> source)
+ {
+ return RepeatInfinite(source).Catch();
+ }
+
+ public virtual IObservable<TSource> Retry<TSource>(IObservable<TSource> source, int retryCount)
+ {
+ return Enumerable.Repeat(source, retryCount).Catch();
+ }
+
+ #endregion
+
+ #region + Scan +
+
+ public virtual IObservable<TAccumulate> Scan<TSource, TAccumulate>(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
+ {
+#if !NO_PERF
+ return new Scan<TSource, TAccumulate>(source, seed, accumulator);
+#else
+ return Defer(() =>
+ {
+ var accumulation = default(TAccumulate);
+ var hasAccumulation = false;
+ return source.Select(x =>
+ {
+ if (hasAccumulation)
+ accumulation = accumulator(accumulation, x);
+ else
+ {
+ accumulation = accumulator(seed, x);
+ hasAccumulation = true;
+ }
+ return accumulation;
+ });
+ });
+#endif
+ }
+
+ public virtual IObservable<TSource> Scan<TSource>(IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
+ {
+#if !NO_PERF
+ return new Scan<TSource>(source, accumulator);
+#else
+ return Defer(() =>
+ {
+ var accumulation = default(TSource);
+ var hasAccumulation = false;
+ return source.Select(x =>
+ {
+ if (hasAccumulation)
+ accumulation = accumulator(accumulation, x);
+ else
+ {
+ accumulation = x;
+ hasAccumulation = true;
+ }
+ return accumulation;
+ });
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + SkipLast +
+
+ public virtual IObservable<TSource> SkipLast<TSource>(IObservable<TSource> source, int count)
+ {
+#if !NO_PERF
+ return new SkipLast<TSource>(source, count);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var q = new Queue<TSource>();
+
+ return source.Subscribe(
+ x =>
+ {
+ q.Enqueue(x);
+ if (q.Count > count)
+ observer.OnNext(q.Dequeue());
+ },
+ observer.OnError,
+ observer.OnCompleted);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region - StartWith -
+
+ public virtual IObservable<TSource> StartWith<TSource>(IObservable<TSource> source, params TSource[] values)
+ {
+ return StartWith_<TSource>(source, SchedulerDefaults.ConstantTimeOperations, values);
+ }
+
+ public virtual IObservable<TSource> StartWith<TSource>(IObservable<TSource> source, IScheduler scheduler, params TSource[] values)
+ {
+ return StartWith_<TSource>(source, scheduler, values);
+ }
+
+ private static IObservable<TSource> StartWith_<TSource>(IObservable<TSource> source, IScheduler scheduler, params TSource[] values)
+ {
+ return values.ToObservable(scheduler).Concat(source);
+ }
+
+ #endregion
+
+ #region + TakeLast +
+
+ public virtual IObservable<TSource> TakeLast<TSource>(IObservable<TSource> source, int count)
+ {
+ return TakeLast_(source, count, SchedulerDefaults.Iteration);
+ }
+
+ public virtual IObservable<TSource> TakeLast<TSource>(IObservable<TSource> source, int count, IScheduler scheduler)
+ {
+ return TakeLast_(source, count, scheduler);
+ }
+
+ private static IObservable<TSource> TakeLast_<TSource>(IObservable<TSource> source, int count, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new TakeLast<TSource>(source, count, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var q = new Queue<TSource>();
+
+ var g = new CompositeDisposable();
+
+ g.Add(source.Subscribe(
+ x =>
+ {
+ q.Enqueue(x);
+ if (q.Count > count)
+ q.Dequeue();
+ },
+ observer.OnError,
+ () =>
+ {
+ g.Add(scheduler.Schedule(rec =>
+ {
+ if (q.Count > 0)
+ {
+ observer.OnNext(q.Dequeue());
+ rec();
+ }
+ else
+ {
+ observer.OnCompleted();
+ }
+ }));
+ }
+ ));
+
+ return g;
+ });
+#endif
+ }
+
+ public virtual IObservable<IList<TSource>> TakeLastBuffer<TSource>(IObservable<TSource> source, int count)
+ {
+#if !NO_PERF
+ return new TakeLastBuffer<TSource>(source, count);
+#else
+ return new AnonymousObservable<IList<TSource>>(observer =>
+ {
+ var q = new Queue<TSource>();
+
+ return source.Subscribe(
+ x =>
+ {
+ q.Enqueue(x);
+ if (q.Count > count)
+ q.Dequeue();
+ },
+ observer.OnError,
+ () =>
+ {
+ observer.OnNext(q.ToList());
+ observer.OnCompleted();
+ });
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Window +
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, int count, int skip)
+ {
+ return Window_<TSource>(source, count, skip);
+ }
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, int count)
+ {
+ return Window_<TSource>(source, count, count);
+ }
+
+ private static IObservable<IObservable<TSource>> Window_<TSource>(IObservable<TSource> source, int count, int skip)
+ {
+#if !NO_PERF
+ return new Window<TSource>(source, count, skip);
+#else
+ return new AnonymousObservable<IObservable<TSource>>(observer =>
+ {
+ var q = new Queue<ISubject<TSource>>();
+ var n = 0;
+
+ var m = new SingleAssignmentDisposable();
+ var refCountDisposable = new RefCountDisposable(m);
+
+ Action createWindow = () =>
+ {
+ var s = new Subject<TSource>();
+ q.Enqueue(s);
+ observer.OnNext(s.AddRef(refCountDisposable));
+ };
+
+ createWindow();
+
+ m.Disposable = source.Subscribe(
+ x =>
+ {
+ foreach (var s in q)
+ s.OnNext(x);
+
+ var c = n - count + 1;
+ if (c >= 0 && c % skip == 0)
+ {
+ var s = q.Dequeue();
+ s.OnCompleted();
+ }
+
+ n++;
+ if (n % skip == 0)
+ createWindow();
+ },
+ exception =>
+ {
+ while (q.Count > 0)
+ q.Dequeue().OnError(exception);
+
+ observer.OnError(exception);
+ },
+ () =>
+ {
+ while (q.Count > 0)
+ q.Dequeue().OnCompleted();
+
+ observer.OnCompleted();
+ }
+ );
+
+ return refCountDisposable;
+ });
+#endif
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.StandardSequenceOperators.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.StandardSequenceOperators.cs
new file mode 100644
index 0000000..30bbf70
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.StandardSequenceOperators.cs
@@ -0,0 +1,1265 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+#if !NO_TPL
+using System.Reactive.Threading.Tasks;
+using System.Threading;
+using System.Threading.Tasks;
+#endif
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ internal partial class QueryLanguage
+ {
+ #region + Cast +
+
+ public virtual IObservable<TResult> Cast<TResult>(IObservable<object> source)
+ {
+#if !NO_PERF
+ return new Cast<object, TResult>(source);
+#else
+ return source.Select(x => (TResult)x);
+#endif
+ }
+
+ #endregion
+
+ #region + DefaultIfEmpty +
+
+ public virtual IObservable<TSource> DefaultIfEmpty<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new DefaultIfEmpty<TSource>(source, default(TSource));
+#else
+ return DefaultIfEmpty_(source, default(TSource));
+#endif
+ }
+
+ public virtual IObservable<TSource> DefaultIfEmpty<TSource>(IObservable<TSource> source, TSource defaultValue)
+ {
+#if !NO_PERF
+ return new DefaultIfEmpty<TSource>(source, defaultValue);
+#else
+ return DefaultIfEmpty_(source, defaultValue);
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TSource> DefaultIfEmpty_<TSource>(IObservable<TSource> source, TSource defaultValue)
+ {
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var found = false;
+ return source.Subscribe(
+ x =>
+ {
+ found = true;
+ observer.OnNext(x);
+ },
+ observer.OnError,
+ () =>
+ {
+ if (!found)
+ observer.OnNext(defaultValue);
+ observer.OnCompleted();
+ }
+ );
+ });
+ }
+#endif
+
+ #endregion
+
+ #region + Distinct +
+
+ public virtual IObservable<TSource> Distinct<TSource>(IObservable<TSource> source)
+ {
+#if !NO_PERF
+ return new Distinct<TSource, TSource>(source, x => x, EqualityComparer<TSource>.Default);
+#else
+ return Distinct_(source, x => x, EqualityComparer<TSource>.Default);
+#endif
+ }
+
+ public virtual IObservable<TSource> Distinct<TSource>(IObservable<TSource> source, IEqualityComparer<TSource> comparer)
+ {
+#if !NO_PERF
+ return new Distinct<TSource, TSource>(source, x => x, comparer);
+#else
+ return Distinct_(source, x => x, comparer);
+#endif
+ }
+
+ public virtual IObservable<TSource> Distinct<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+#if !NO_PERF
+ return new Distinct<TSource, TKey>(source, keySelector, EqualityComparer<TKey>.Default);
+#else
+ return Distinct_(source, keySelector, EqualityComparer<TKey>.Default);
+#endif
+ }
+
+ public virtual IObservable<TSource> Distinct<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+#if !NO_PERF
+ return new Distinct<TSource, TKey>(source, keySelector, comparer);
+#else
+ return Distinct_(source, keySelector, comparer);
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TSource> Distinct_<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var hashSet = new HashSet<TKey>(comparer);
+ return source.Subscribe(
+ x =>
+ {
+ var key = default(TKey);
+ var hasAdded = false;
+
+ try
+ {
+ key = keySelector(x);
+ hasAdded = hashSet.Add(key);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ if (hasAdded)
+ observer.OnNext(x);
+ },
+ observer.OnError,
+ observer.OnCompleted
+ );
+ });
+ }
+#endif
+
+ #endregion
+
+ #region + GroupBy +
+
+ public virtual IObservable<IGroupedObservable<TKey, TElement>> GroupBy<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
+ {
+ return GroupBy_<TSource, TKey, TElement>(source, keySelector, elementSelector, EqualityComparer<TKey>.Default);
+ }
+
+ public virtual IObservable<IGroupedObservable<TKey, TSource>> GroupBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
+ {
+ return GroupBy_<TSource, TKey, TSource>(source, keySelector, x => x, comparer);
+ }
+
+ public virtual IObservable<IGroupedObservable<TKey, TSource>> GroupBy<TSource, TKey>(IObservable<TSource> source, Func<TSource, TKey> keySelector)
+ {
+ return GroupBy_<TSource, TKey, TSource>(source, keySelector, x => x, EqualityComparer<TKey>.Default);
+ }
+
+ public virtual IObservable<IGroupedObservable<TKey, TElement>> GroupBy<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+ {
+ return GroupBy_<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
+ }
+
+ private static IObservable<IGroupedObservable<TKey, TElement>> GroupBy_<TSource, TKey, TElement>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+ {
+#if !NO_PERF
+ return new GroupBy<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
+#else
+ return GroupByUntil_<TSource, TKey, TElement, Unit>(source, keySelector, elementSelector, _ => Observable.Never<Unit>(), comparer);
+#endif
+ }
+
+ #endregion
+
+ #region + GroupByUntil +
+
+ public virtual IObservable<IGroupedObservable<TKey, TElement>> GroupByUntil<TSource, TKey, TElement, TDuration>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedObservable<TKey, TElement>, IObservable<TDuration>> durationSelector, IEqualityComparer<TKey> comparer)
+ {
+ return GroupByUntil_<TSource, TKey, TElement, TDuration>(source, keySelector, elementSelector, durationSelector, comparer);
+ }
+
+ public virtual IObservable<IGroupedObservable<TKey, TElement>> GroupByUntil<TSource, TKey, TElement, TDuration>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedObservable<TKey, TElement>, IObservable<TDuration>> durationSelector)
+ {
+ return GroupByUntil_<TSource, TKey, TElement, TDuration>(source, keySelector, elementSelector, durationSelector, EqualityComparer<TKey>.Default);
+ }
+
+ public virtual IObservable<IGroupedObservable<TKey, TSource>> GroupByUntil<TSource, TKey, TDuration>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<IGroupedObservable<TKey, TSource>, IObservable<TDuration>> durationSelector, IEqualityComparer<TKey> comparer)
+ {
+ return GroupByUntil_<TSource, TKey, TSource, TDuration>(source, keySelector, x => x, durationSelector, comparer);
+ }
+
+ public virtual IObservable<IGroupedObservable<TKey, TSource>> GroupByUntil<TSource, TKey, TDuration>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<IGroupedObservable<TKey, TSource>, IObservable<TDuration>> durationSelector)
+ {
+ return GroupByUntil_<TSource, TKey, TSource, TDuration>(source, keySelector, x => x, durationSelector, EqualityComparer<TKey>.Default);
+ }
+
+ private static IObservable<IGroupedObservable<TKey, TElement>> GroupByUntil_<TSource, TKey, TElement, TDuration>(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<IGroupedObservable<TKey, TElement>, IObservable<TDuration>> durationSelector, IEqualityComparer<TKey> comparer)
+ {
+#if !NO_PERF
+ return new GroupByUntil<TSource, TKey, TElement, TDuration>(source, keySelector, elementSelector, durationSelector, comparer);
+#else
+ return new AnonymousObservable<IGroupedObservable<TKey, TElement>>(observer =>
+ {
+ var map = new Dictionary<TKey, ISubject<TElement>>(comparer);
+
+ var groupDisposable = new CompositeDisposable();
+ var refCountDisposable = new RefCountDisposable(groupDisposable);
+
+ groupDisposable.Add(source.Subscribe(x =>
+ {
+ var key = default(TKey);
+ try
+ {
+ key = keySelector(x);
+ }
+ catch (Exception exception)
+ {
+ lock (map)
+ foreach (var w in map.Values.ToArray())
+ w.OnError(exception);
+ observer.OnError(exception);
+ return;
+ }
+
+ var fireNewMapEntry = false;
+ var writer = default(ISubject<TElement>);
+ try
+ {
+ lock (map)
+ {
+ if (!map.TryGetValue(key, out writer))
+ {
+ writer = new Subject<TElement>();
+ map.Add(key, writer);
+ fireNewMapEntry = true;
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ lock (map)
+ {
+ foreach (var w in map.Values.ToArray())
+ w.OnError(exception);
+ }
+ observer.OnError(exception);
+ return;
+ }
+
+ if (fireNewMapEntry)
+ {
+ var group = new GroupedObservable<TKey, TElement>(key, writer, refCountDisposable);
+
+ var durationGroup = new GroupedObservable<TKey, TElement>(key, writer);
+ var duration = default(IObservable<TDuration>);
+ try
+ {
+ duration = durationSelector(durationGroup);
+ }
+ catch (Exception exception)
+ {
+ foreach (var w in map.Values.ToArray())
+ w.OnError(exception);
+ observer.OnError(exception);
+ return;
+ }
+
+ observer.OnNext(group);
+
+ var md = new SingleAssignmentDisposable();
+ groupDisposable.Add(md);
+
+ Action expire = () =>
+ {
+ lock (map)
+ {
+ if (map.Remove(key))
+ writer.OnCompleted();
+ }
+
+ groupDisposable.Remove(md);
+ };
+
+ md.Disposable = duration.Take(1).Subscribe(
+ _ => { },
+ exception =>
+ {
+ lock (map)
+ foreach (var o in map.Values.ToArray())
+ o.OnError(exception);
+ observer.OnError(exception);
+ },
+ expire);
+ }
+
+ var element = default(TElement);
+ try
+ {
+ element = elementSelector(x);
+ }
+ catch (Exception exception)
+ {
+ lock (map)
+ foreach (var w in map.Values.ToArray())
+ w.OnError(exception);
+ observer.OnError(exception);
+ return;
+ }
+
+ writer.OnNext(element);
+ },
+ e =>
+ {
+ lock (map)
+ foreach (var w in map.Values.ToArray())
+ w.OnError(e);
+ observer.OnError(e);
+ },
+ () =>
+ {
+ lock (map)
+ foreach (var w in map.Values.ToArray())
+ w.OnCompleted();
+ observer.OnCompleted();
+ }));
+
+ return refCountDisposable;
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + GroupJoin +
+
+ public virtual IObservable<TResult> GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, IObservable<TRight>, TResult> resultSelector)
+ {
+ return GroupJoin_<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(left, right, leftDurationSelector, rightDurationSelector, resultSelector);
+ }
+
+ private static IObservable<TResult> GroupJoin_<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, IObservable<TRight>, TResult> resultSelector)
+ {
+#if !NO_PERF
+ return new GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(left, right, leftDurationSelector, rightDurationSelector, resultSelector);
+#else
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var gate = new object();
+ var group = new CompositeDisposable();
+ var r = new RefCountDisposable(group);
+ var leftMap = new Dictionary<int, IObserver<TRight>>();
+ var rightMap = new Dictionary<int, TRight>();
+ var leftID = 0;
+ var rightID = 0;
+
+ group.Add(left.Subscribe(
+ value =>
+ {
+ var s = new Subject<TRight>();
+ var id = 0;
+ lock (gate)
+ {
+ id = leftID++;
+ leftMap.Add(id, s);
+ }
+
+ lock (gate)
+ {
+ var result = default(TResult);
+ try
+ {
+ result = resultSelector(value, s.AddRef(r));
+ }
+ catch (Exception exception)
+ {
+ foreach (var o in leftMap.Values.ToArray())
+ o.OnError(exception);
+ observer.OnError(exception);
+ return;
+ }
+ observer.OnNext(result);
+
+ foreach (var rightValue in rightMap.Values.ToArray())
+ {
+ s.OnNext(rightValue);
+ }
+ }
+
+ var md = new SingleAssignmentDisposable();
+ group.Add(md);
+
+ Action expire = () =>
+ {
+ lock (gate)
+ if (leftMap.Remove(id))
+ s.OnCompleted();
+
+ group.Remove(md);
+ };
+
+ var duration = default(IObservable<TLeftDuration>);
+ try
+ {
+ duration = leftDurationSelector(value);
+ }
+ catch (Exception exception)
+ {
+ lock (gate)
+ {
+ foreach (var o in leftMap.Values.ToArray())
+ o.OnError(exception);
+ observer.OnError(exception);
+ }
+ return;
+ }
+
+ md.Disposable = duration.Take(1).Subscribe(
+ _ => { },
+ exception =>
+ {
+ lock (gate)
+ {
+ foreach (var o in leftMap.Values.ToArray())
+ o.OnError(exception);
+ observer.OnError(exception);
+ }
+ },
+ expire);
+ },
+ exception =>
+ {
+ lock (gate)
+ {
+ foreach (var o in leftMap.Values.ToArray())
+ o.OnError(exception);
+ observer.OnError(exception);
+ }
+ },
+ () =>
+ {
+ lock (gate)
+ observer.OnCompleted();
+ }));
+
+ group.Add(right.Subscribe(
+ value =>
+ {
+ var id = 0;
+ lock (gate)
+ {
+ id = rightID++;
+ rightMap.Add(id, value);
+ }
+
+ var md = new SingleAssignmentDisposable();
+ group.Add(md);
+
+ Action expire = () =>
+ {
+ lock (gate)
+ rightMap.Remove(id);
+
+ group.Remove(md);
+ };
+
+ var duration = default(IObservable<TRightDuration>);
+ try
+ {
+ duration = rightDurationSelector(value);
+ }
+ catch (Exception exception)
+ {
+ lock (gate)
+ {
+ foreach (var o in leftMap.Values.ToArray())
+ o.OnError(exception);
+ observer.OnError(exception);
+ }
+ return;
+ }
+ md.Disposable = duration.Take(1).Subscribe(
+ _ => { },
+ exception =>
+ {
+ lock (gate)
+ {
+ foreach (var o in leftMap.Values.ToArray())
+ o.OnError(exception);
+ observer.OnError(exception);
+ }
+ },
+ expire);
+
+ lock (gate)
+ {
+ foreach (var o in leftMap.Values.ToArray())
+ o.OnNext(value);
+ }
+ },
+ exception =>
+ {
+ lock (gate)
+ {
+ foreach (var o in leftMap.Values.ToArray())
+ o.OnError(exception);
+ observer.OnError(exception);
+ }
+ }));
+
+ return r;
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Join +
+
+ public virtual IObservable<TResult> Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, TRight, TResult> resultSelector)
+ {
+ return Join_<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(left, right, leftDurationSelector, rightDurationSelector, resultSelector);
+ }
+
+ private static IObservable<TResult> Join_<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, TRight, TResult> resultSelector)
+ {
+#if !NO_PERF
+ return new Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(left, right, leftDurationSelector, rightDurationSelector, resultSelector);
+#else
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var gate = new object();
+ var leftDone = false;
+ var rightDone = false;
+ var group = new CompositeDisposable();
+ var leftMap = new Dictionary<int, TLeft>();
+ var rightMap = new Dictionary<int, TRight>();
+ var leftID = 0;
+ var rightID = 0;
+
+ group.Add(left.Subscribe(
+ value =>
+ {
+ var id = 0;
+ lock (gate)
+ {
+ id = leftID++;
+ leftMap.Add(id, value);
+ }
+
+ var md = new SingleAssignmentDisposable();
+ group.Add(md);
+
+ Action expire = () =>
+ {
+ lock (gate)
+ {
+ if (leftMap.Remove(id) && leftMap.Count == 0 && leftDone)
+ observer.OnCompleted();
+ }
+
+ group.Remove(md);
+ };
+
+ var duration = default(IObservable<TLeftDuration>);
+ try
+ {
+ duration = leftDurationSelector(value);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ md.Disposable = duration.Take(1).Subscribe(
+ _ => { },
+ error =>
+ {
+ lock (gate)
+ observer.OnError(error);
+ },
+ expire);
+
+ lock (gate)
+ {
+ foreach (var rightValue in rightMap.Values.ToArray())
+ {
+ var result = default(TResult);
+ try
+ {
+ result = resultSelector(value, rightValue);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ observer.OnNext(result);
+ }
+ }
+ },
+ error =>
+ {
+ lock (gate)
+ observer.OnError(error);
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ leftDone = true;
+ if (rightDone || leftMap.Count == 0)
+ observer.OnCompleted();
+ }
+ }));
+
+ group.Add(right.Subscribe(
+ value =>
+ {
+ var id = 0;
+ lock (gate)
+ {
+ id = rightID++;
+ rightMap.Add(id, value);
+ }
+
+ var md = new SingleAssignmentDisposable();
+ group.Add(md);
+
+ Action expire = () =>
+ {
+ lock (gate)
+ {
+ if (rightMap.Remove(id) && rightMap.Count == 0 && rightDone)
+ observer.OnCompleted();
+ }
+
+ group.Remove(md);
+ };
+
+ var duration = default(IObservable<TRightDuration>);
+ try
+ {
+ duration = rightDurationSelector(value);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ md.Disposable = duration.Take(1).Subscribe(
+ _ => { },
+ error =>
+ {
+ lock (gate)
+ observer.OnError(error);
+ },
+ expire);
+
+ lock (gate)
+ {
+ foreach (var leftValue in leftMap.Values.ToArray())
+ {
+ var result = default(TResult);
+ try
+ {
+ result = resultSelector(leftValue, value);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ observer.OnNext(result);
+ }
+ }
+ },
+ error =>
+ {
+ lock (gate)
+ observer.OnError(error);
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ rightDone = true;
+ if (leftDone || rightMap.Count == 0)
+ observer.OnCompleted();
+ }
+ }));
+
+ return group;
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + OfType +
+
+ public virtual IObservable<TResult> OfType<TResult>(IObservable<object> source)
+ {
+#if !NO_PERF
+ return new OfType<object, TResult>(source);
+#else
+ return source.Where(x => x is TResult).Cast<TResult>();
+#endif
+ }
+
+ #endregion
+
+ #region + Select +
+
+ public virtual IObservable<TResult> Select<TSource, TResult>(IObservable<TSource> source, Func<TSource, TResult> selector)
+ {
+#if !NO_PERF
+ var select = source as Select<TSource>;
+ if (select != null)
+ return select.Ω(selector);
+
+ return new Select<TSource, TResult>(source, selector);
+#else
+ var s = source as SelectObservable<TSource>;
+ if (s != null)
+ return s.Select(selector);
+
+ return new SelectObservable<TSource, TResult>(source, selector);
+#endif
+ }
+
+#if NO_PERF
+ abstract class SelectObservable<TResult> : ObservableBase<TResult>
+ {
+ public abstract IObservable<TResult2> Select<TResult2>(Func<TResult, TResult2> selector);
+ }
+
+ class SelectObservable<TSource, TResult> : SelectObservable<TResult>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, TResult> _selector;
+
+ public SelectObservable(IObservable<TSource> source, Func<TSource, TResult> selector)
+ {
+ _source = source;
+ _selector = selector;
+ }
+
+ protected override IDisposable SubscribeCore(IObserver<TResult> observer)
+ {
+ return _source.Subscribe(new Observer(observer, _selector));
+ }
+
+ public override IObservable<TResult2> Select<TResult2>(Func<TResult, TResult2> selector)
+ {
+ return new SelectObservable<TSource, TResult2>(_source, x => selector(_selector(x)));
+ }
+
+ class Observer : ObserverBase<TSource>
+ {
+ private readonly IObserver<TResult> _observer;
+ private readonly Func<TSource, TResult> _selector;
+
+ public Observer(IObserver<TResult> observer, Func<TSource, TResult> selector)
+ {
+ _observer = observer;
+ _selector = selector;
+ }
+
+ protected override void OnNextCore(TSource value)
+ {
+ TResult result;
+ try
+ {
+ result = _selector(value);
+ }
+ catch (Exception exception)
+ {
+ _observer.OnError(exception);
+ return;
+ }
+ _observer.OnNext(result);
+ }
+
+ protected override void OnErrorCore(Exception error)
+ {
+ _observer.OnError(error);
+ }
+
+ protected override void OnCompletedCore()
+ {
+ _observer.OnCompleted();
+ }
+ }
+ }
+#endif
+
+ public virtual IObservable<TResult> Select<TSource, TResult>(IObservable<TSource> source, Func<TSource, int, TResult> selector)
+ {
+#if !NO_PERF
+ return new Select<TSource, TResult>(source, selector);
+#else
+ return Defer(() =>
+ {
+ var index = 0;
+ return source.Select(x => selector(x, checked(index++)));
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + SelectMany +
+
+ public virtual IObservable<TOther> SelectMany<TSource, TOther>(IObservable<TSource> source, IObservable<TOther> other)
+ {
+ return SelectMany_<TSource, TOther>(source, _ => other);
+ }
+
+ public virtual IObservable<TResult> SelectMany<TSource, TResult>(IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector)
+ {
+ return SelectMany_<TSource, TResult>(source, selector);
+ }
+
+#if !NO_TPL
+ public virtual IObservable<TResult> SelectMany<TSource, TResult>(IObservable<TSource> source, Func<TSource, Task<TResult>> selector)
+ {
+ return SelectMany_<TSource, TResult>(source, x => selector(x).ToObservable());
+ }
+
+ public virtual IObservable<TResult> SelectMany<TSource, TResult>(IObservable<TSource> source, Func<TSource, CancellationToken, Task<TResult>> selector)
+ {
+ return SelectMany_<TSource, TResult>(source, x => FromAsync(ct => selector(x, ct)));
+ }
+#endif
+
+ public virtual IObservable<TResult> SelectMany<TSource, TCollection, TResult>(IObservable<TSource> source, Func<TSource, IObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
+ {
+ return SelectMany_<TSource, TCollection, TResult>(source, collectionSelector, resultSelector);
+ }
+
+#if !NO_TPL
+ public virtual IObservable<TResult> SelectMany<TSource, TTaskResult, TResult>(IObservable<TSource> source, Func<TSource, Task<TTaskResult>> taskSelector, Func<TSource, TTaskResult, TResult> resultSelector)
+ {
+ return SelectMany_<TSource, TTaskResult, TResult>(source, x => taskSelector(x).ToObservable(), resultSelector);
+ }
+
+ public virtual IObservable<TResult> SelectMany<TSource, TTaskResult, TResult>(IObservable<TSource> source, Func<TSource, CancellationToken, Task<TTaskResult>> taskSelector, Func<TSource, TTaskResult, TResult> resultSelector)
+ {
+ return SelectMany_<TSource, TTaskResult, TResult>(source, x => FromAsync(ct => taskSelector(x, ct)), resultSelector);
+ }
+#endif
+
+ private static IObservable<TResult> SelectMany_<TSource, TResult>(IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector)
+ {
+#if !NO_PERF
+ return new SelectMany<TSource, TResult>(source, selector);
+#else
+ return source.Select(selector).Merge();
+#endif
+ }
+
+ private static IObservable<TResult> SelectMany_<TSource, TCollection, TResult>(IObservable<TSource> source, Func<TSource, IObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
+ {
+#if !NO_PERF
+ return new SelectMany<TSource, TCollection, TResult>(source, collectionSelector, resultSelector);
+#else
+ return SelectMany_<TSource, TResult>(source, x => collectionSelector(x).Select(y => resultSelector(x, y)));
+#endif
+ }
+
+ public virtual IObservable<TResult> SelectMany<TSource, TResult>(IObservable<TSource> source, Func<TSource, IObservable<TResult>> onNext, Func<Exception, IObservable<TResult>> onError, Func<IObservable<TResult>> onCompleted)
+ {
+#if !NO_PERF
+ return new SelectMany<TSource, TResult>(source, onNext, onError, onCompleted);
+#else
+ return source.Materialize().SelectMany(notification =>
+ {
+ if (notification.Kind == NotificationKind.OnNext)
+ return onNext(notification.Value);
+ else if (notification.Kind == NotificationKind.OnError)
+ return onError(notification.Exception);
+ else
+ return onCompleted();
+ });
+#endif
+ }
+
+ public virtual IObservable<TResult> SelectMany<TSource, TResult>(IObservable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
+ {
+#if !NO_PERF
+ return new SelectMany<TSource, TResult>(source, selector);
+#else
+ return SelectMany_<TSource, TResult, TResult>(source, selector, (_, x) => x);
+#endif
+ }
+
+ public virtual IObservable<TResult> SelectMany<TSource, TCollection, TResult>(IObservable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
+ {
+ return SelectMany_<TSource, TCollection, TResult>(source, collectionSelector, resultSelector);
+ }
+
+ private static IObservable<TResult> SelectMany_<TSource, TCollection, TResult>(IObservable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
+ {
+#if !NO_PERF
+ return new SelectMany<TSource, TCollection, TResult>(source, collectionSelector, resultSelector);
+#else
+ return new AnonymousObservable<TResult>(observer =>
+ source.Subscribe(
+ x =>
+ {
+ var xs = default(IEnumerable<TCollection>);
+ try
+ {
+ xs = collectionSelector(x);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ var e = xs.GetEnumerator();
+
+ try
+ {
+ var hasNext = true;
+ while (hasNext)
+ {
+ hasNext = false;
+ var current = default(TResult);
+
+ try
+ {
+ hasNext = e.MoveNext();
+ if (hasNext)
+ current = resultSelector(x, e.Current);
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ if (hasNext)
+ observer.OnNext(current);
+ }
+ }
+ finally
+ {
+ if (e != null)
+ e.Dispose();
+ }
+ },
+ observer.OnError,
+ observer.OnCompleted
+ )
+ );
+#endif
+ }
+
+ #endregion
+
+ #region + Skip +
+
+ public virtual IObservable<TSource> Skip<TSource>(IObservable<TSource> source, int count)
+ {
+#if !NO_PERF
+ var skip = source as Skip<TSource>;
+ if (skip != null && skip._scheduler == null)
+ return skip.Ω(count);
+
+ return new Skip<TSource>(source, count);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var remaining = count;
+ return source.Subscribe(
+ x =>
+ {
+ if (remaining <= 0)
+ observer.OnNext(x);
+ else
+ remaining--;
+ },
+ observer.OnError,
+ observer.OnCompleted);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + SkipWhile +
+
+ public virtual IObservable<TSource> SkipWhile<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new SkipWhile<TSource>(source, predicate);
+#else
+ return SkipWhile_(source, (x, i) => predicate(x));
+#endif
+ }
+
+ public virtual IObservable<TSource> SkipWhile<TSource>(IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+#if !NO_PERF
+ return new SkipWhile<TSource>(source, predicate);
+#else
+ return SkipWhile_(source, predicate);
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TSource> SkipWhile_<TSource>(IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var running = false;
+ var i = 0;
+ return source.Subscribe(
+ x =>
+ {
+ if (!running)
+ try
+ {
+ running = !predicate(x, checked(i++));
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+ if (running)
+ observer.OnNext(x);
+ },
+ observer.OnError,
+ observer.OnCompleted);
+ });
+ }
+#endif
+
+ #endregion
+
+ #region + Take +
+
+ public virtual IObservable<TSource> Take<TSource>(IObservable<TSource> source, int count)
+ {
+ if (count == 0)
+ return Empty<TSource>();
+
+ return Take_(source, count);
+ }
+
+ public virtual IObservable<TSource> Take<TSource>(IObservable<TSource> source, int count, IScheduler scheduler)
+ {
+ if (count == 0)
+ return Empty<TSource>(scheduler);
+
+ return Take_(source, count);
+ }
+
+#if !NO_PERF
+ private static IObservable<TSource> Take_<TSource>(IObservable<TSource> source, int count)
+ {
+ var take = source as Take<TSource>;
+ if (take != null && take._scheduler == null)
+ return take.Ω(count);
+
+ return new Take<TSource>(source, count);
+ }
+#else
+ private static IObservable<TSource> Take_<TSource>(IObservable<TSource> source, int count)
+ {
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var remaining = count;
+
+ return source.Subscribe(
+ x =>
+ {
+ if (remaining > 0)
+ {
+ --remaining;
+ observer.OnNext(x);
+ if (remaining == 0)
+ observer.OnCompleted();
+ }
+ },
+ observer.OnError,
+ observer.OnCompleted);
+ });
+ }
+#endif
+
+ #endregion
+
+ #region + TakeWhile +
+
+ public virtual IObservable<TSource> TakeWhile<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ return new TakeWhile<TSource>(source, predicate);
+#else
+ return TakeWhile_(source, (x, i) => predicate(x));
+#endif
+ }
+
+ public virtual IObservable<TSource> TakeWhile<TSource>(IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+#if !NO_PERF
+ return new TakeWhile<TSource>(source, predicate);
+#else
+ return TakeWhile_(source, predicate);
+#endif
+ }
+
+#if NO_PERF
+ private static IObservable<TSource> TakeWhile_<TSource>(IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var running = true;
+ var i = 0;
+ return source.Subscribe(
+ x =>
+ {
+ if (running)
+ {
+ try
+ {
+ running = predicate(x, checked(i++));
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+ if (running)
+ observer.OnNext(x);
+ else
+ observer.OnCompleted();
+ }
+ },
+ observer.OnError,
+ observer.OnCompleted);
+ });
+ }
+#endif
+
+ #endregion
+
+ #region + Where +
+
+ public virtual IObservable<TSource> Where<TSource>(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+#if !NO_PERF
+ var where = source as Where<TSource>;
+ if (where != null)
+ return where.Ω(predicate);
+
+ return new Where<TSource>(source, predicate);
+#else
+ var w = source as WhereObservable<TSource>;
+ if (w != null)
+ return w.Where(predicate);
+
+ return new WhereObservable<TSource>(source, predicate);
+#endif
+ }
+
+#if NO_PERF
+ class WhereObservable<TSource> : ObservableBase<TSource>
+ {
+ private readonly IObservable<TSource> _source;
+ private readonly Func<TSource, bool> _predicate;
+
+ public WhereObservable(IObservable<TSource> source, Func<TSource, bool> predicate)
+ {
+ _source = source;
+ _predicate = predicate;
+ }
+
+ protected override IDisposable SubscribeCore(IObserver<TSource> observer)
+ {
+ return _source.Subscribe(new Observer(observer, _predicate));
+ }
+
+ public IObservable<TSource> Where(Func<TSource, bool> predicate)
+ {
+ return new WhereObservable<TSource>(_source, x => _predicate(x) && predicate(x));
+ }
+
+ class Observer : ObserverBase<TSource>
+ {
+ private readonly IObserver<TSource> _observer;
+ private readonly Func<TSource, bool> _predicate;
+
+ public Observer(IObserver<TSource> observer, Func<TSource, bool> predicate)
+ {
+ _observer = observer;
+ _predicate = predicate;
+ }
+
+ protected override void OnNextCore(TSource value)
+ {
+ bool shouldRun;
+ try
+ {
+ shouldRun = _predicate(value);
+ }
+ catch (Exception exception)
+ {
+ _observer.OnError(exception);
+ return;
+ }
+ if (shouldRun)
+ _observer.OnNext(value);
+ }
+
+ protected override void OnErrorCore(Exception error)
+ {
+ _observer.OnError(error);
+ }
+
+ protected override void OnCompletedCore()
+ {
+ _observer.OnCompleted();
+ }
+ }
+ }
+#endif
+
+ public virtual IObservable<TSource> Where<TSource>(IObservable<TSource> source, Func<TSource, int, bool> predicate)
+ {
+#if !NO_PERF
+ return new Where<TSource>(source, predicate);
+#else
+ return Defer(() =>
+ {
+ var index = 0;
+ return source.Where(x => predicate(x, checked(index++)));
+ });
+#endif
+ }
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Time.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Time.cs
new file mode 100644
index 0000000..161e1c1
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Time.cs
@@ -0,0 +1,1907 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reactive.Concurrency;
+using System.Reactive.Disposables;
+using System.Reactive.Subjects;
+
+namespace System.Reactive.Linq
+{
+#if !NO_PERF
+ using Observαble;
+#endif
+
+ internal partial class QueryLanguage
+ {
+ #region + Buffer +
+
+ #region TimeSpan only
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan)
+ {
+ return Buffer_<TSource>(source, timeSpan, timeSpan, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan, IScheduler scheduler)
+ {
+ return Buffer_<TSource>(source, timeSpan, timeSpan, scheduler);
+ }
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift)
+ {
+ return Buffer_<TSource>(source, timeSpan, timeShift, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler)
+ {
+ return Buffer_<TSource>(source, timeSpan, timeShift, scheduler);
+ }
+
+ private static IObservable<IList<TSource>> Buffer_<TSource>(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Buffer<TSource>(source, timeSpan, timeShift, scheduler);
+#else
+ return source.Window(timeSpan, timeShift, scheduler).SelectMany(Observable.ToList);
+#endif
+ }
+
+ #endregion
+
+ #region TimeSpan + int
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan, int count)
+ {
+ return Buffer_<TSource>(source, timeSpan, count, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<IList<TSource>> Buffer<TSource>(IObservable<TSource> source, TimeSpan timeSpan, int count, IScheduler scheduler)
+ {
+ return Buffer_<TSource>(source, timeSpan, count, scheduler);
+ }
+
+ private static IObservable<IList<TSource>> Buffer_<TSource>(IObservable<TSource> source, TimeSpan timeSpan, int count, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Buffer<TSource>(source, timeSpan, count, scheduler);
+#else
+ return source.Window(timeSpan, count, scheduler).SelectMany(Observable.ToList);
+#endif
+ }
+
+ #endregion
+
+ #endregion
+
+ #region + Delay +
+
+ #region TimeSpan
+
+ public virtual IObservable<TSource> Delay<TSource>(IObservable<TSource> source, TimeSpan dueTime)
+ {
+ return Delay_<TSource>(source, dueTime, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> Delay<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ return Delay_<TSource>(source, dueTime, scheduler);
+ }
+
+ private static IObservable<TSource> Delay_<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Delay<TSource>(source, dueTime, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var gate = new object();
+ var q = new Queue<Timestamped<Notification<TSource>>>();
+ var active = false;
+ var running = false;
+ var cancelable = new SerialDisposable();
+ var exception = default(Exception);
+
+ var subscription = source.Materialize().Timestamp(scheduler).Subscribe(notification =>
+ {
+ var shouldRun = false;
+
+ lock (gate)
+ {
+ if (notification.Value.Kind == NotificationKind.OnError)
+ {
+ q.Clear();
+ q.Enqueue(notification);
+ exception = notification.Value.Exception;
+ shouldRun = !running;
+ }
+ else
+ {
+ q.Enqueue(new Timestamped<Notification<TSource>>(notification.Value, notification.Timestamp.Add(dueTime)));
+ shouldRun = !active;
+ active = true;
+ }
+ }
+
+ if (shouldRun)
+ {
+ if (exception != null)
+ observer.OnError(exception);
+ else
+ {
+ var d = new SingleAssignmentDisposable();
+ cancelable.Disposable = d;
+ d.Disposable = scheduler.Schedule(dueTime, self =>
+ {
+ lock (gate)
+ {
+ if (exception != null)
+ return;
+ running = true;
+ }
+ Notification<TSource> result;
+
+ do
+ {
+ result = null;
+ lock (gate)
+ {
+ if (q.Count > 0 && q.Peek().Timestamp.CompareTo(scheduler.Now) <= 0)
+ result = q.Dequeue().Value;
+ }
+
+ if (result != null)
+ result.Accept(observer);
+ } while (result != null);
+
+ var shouldRecurse = false;
+ var recurseDueTime = TimeSpan.Zero;
+ var e = default(Exception);
+ lock (gate)
+ {
+ if (q.Count > 0)
+ {
+ shouldRecurse = true;
+ recurseDueTime = TimeSpan.FromTicks(Math.Max(0, q.Peek().Timestamp.Subtract(scheduler.Now).Ticks));
+ }
+ else
+ active = false;
+ e = exception;
+ running = false;
+ }
+ if (e != null)
+ observer.OnError(e);
+ else if (shouldRecurse)
+ self(recurseDueTime);
+ });
+ }
+ }
+ });
+
+ return new CompositeDisposable(subscription, cancelable);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region DateTimeOffset
+
+ public virtual IObservable<TSource> Delay<TSource>(IObservable<TSource> source, DateTimeOffset dueTime)
+ {
+ return Delay_<TSource>(source, dueTime, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> Delay<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
+ {
+ return Delay_<TSource>(source, dueTime, scheduler);
+ }
+
+ private static IObservable<TSource> Delay_<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Delay<TSource>(source, dueTime, scheduler);
+#else
+ return Observable.Defer(() =>
+ {
+ var timeSpan = dueTime.Subtract(scheduler.Now);
+ return Delay_<TSource>(source, timeSpan, scheduler);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region Duration selector
+
+ public virtual IObservable<TSource> Delay<TSource, TDelay>(IObservable<TSource> source, Func<TSource, IObservable<TDelay>> delayDurationSelector)
+ {
+ return Delay_<TSource, TDelay>(source, null, delayDurationSelector);
+ }
+
+ public virtual IObservable<TSource> Delay<TSource, TDelay>(IObservable<TSource> source, IObservable<TDelay> subscriptionDelay, Func<TSource, IObservable<TDelay>> delayDurationSelector)
+ {
+ return Delay_<TSource, TDelay>(source, subscriptionDelay, delayDurationSelector);
+ }
+
+ private static IObservable<TSource> Delay_<TSource, TDelay>(IObservable<TSource> source, IObservable<TDelay> subscriptionDelay, Func<TSource, IObservable<TDelay>> delayDurationSelector)
+ {
+#if !NO_PERF
+ return new Delay<TSource, TDelay>(source, subscriptionDelay, delayDurationSelector);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var delays = new CompositeDisposable();
+
+ var gate = new object();
+ var atEnd = false;
+
+ var done = new Action(() =>
+ {
+ if (atEnd && delays.Count == 0)
+ {
+ observer.OnCompleted();
+ }
+ });
+
+ var subscription = new SerialDisposable();
+
+ var start = new Action(() =>
+ {
+ subscription.Disposable = source.Subscribe(
+ x =>
+ {
+ var delay = default(IObservable<TDelay>);
+ try
+ {
+ delay = delayDurationSelector(x);
+ }
+ catch (Exception error)
+ {
+ lock (gate)
+ observer.OnError(error);
+
+ return;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ delays.Add(d);
+ d.Disposable = delay.Subscribe(
+ _ =>
+ {
+ lock (gate)
+ {
+ observer.OnNext(x);
+
+ delays.Remove(d);
+ done();
+ }
+ },
+ exception =>
+ {
+ lock (gate)
+ observer.OnError(exception);
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ observer.OnNext(x);
+
+ delays.Remove(d);
+ done();
+ }
+ }
+ );
+ },
+ exception =>
+ {
+ lock (gate)
+ {
+ observer.OnError(exception);
+ }
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ atEnd = true;
+ subscription.Dispose();
+
+ done();
+ }
+ }
+ );
+ });
+
+ if (subscriptionDelay == null)
+ {
+ start();
+ }
+ else
+ {
+ subscription.Disposable = subscriptionDelay.Subscribe(
+ _ =>
+ {
+ start();
+ },
+ observer.OnError,
+ start
+ );
+ }
+
+ return new CompositeDisposable(subscription, delays);
+ });
+#endif
+ }
+
+ #endregion
+
+ #endregion
+
+ #region + DelaySubscription +
+
+ public virtual IObservable<TSource> DelaySubscription<TSource>(IObservable<TSource> source, TimeSpan dueTime)
+ {
+ return DelaySubscription_<TSource>(source, dueTime, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> DelaySubscription<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ return DelaySubscription_<TSource>(source, dueTime, scheduler);
+ }
+
+ private static IObservable<TSource> DelaySubscription_<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new DelaySubscription<TSource>(source, dueTime, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var d = new MultipleAssignmentDisposable();
+
+ var dt = Normalize(dueTime);
+
+ d.Disposable = scheduler.Schedule(dt, () =>
+ {
+ d.Disposable = source.Subscribe(observer);
+ });
+
+ return d;
+ });
+#endif
+ }
+
+ public virtual IObservable<TSource> DelaySubscription<TSource>(IObservable<TSource> source, DateTimeOffset dueTime)
+ {
+ return DelaySubscription_<TSource>(source, dueTime, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> DelaySubscription<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
+ {
+ return DelaySubscription_<TSource>(source, dueTime, scheduler);
+ }
+
+ private static IObservable<TSource> DelaySubscription_<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new DelaySubscription<TSource>(source, dueTime, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var d = new MultipleAssignmentDisposable();
+
+ d.Disposable = scheduler.Schedule(dueTime, () =>
+ {
+ d.Disposable = source.Subscribe(observer);
+ });
+
+ return d;
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Generate +
+
+ public virtual IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, TimeSpan> timeSelector)
+ {
+ return Generate_<TState, TResult>(initialState, condition, iterate, resultSelector, timeSelector, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, TimeSpan> timeSelector, IScheduler scheduler)
+ {
+ return Generate_<TState, TResult>(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
+ }
+
+ private static IObservable<TResult> Generate_<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, TimeSpan> timeSelector, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Generate<TState, TResult>(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
+#else
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var state = initialState;
+ var first = true;
+ var hasResult = false;
+ var result = default(TResult);
+ var time = default(TimeSpan);
+ return scheduler.Schedule(TimeSpan.Zero, self =>
+ {
+ if (hasResult)
+ observer.OnNext(result);
+ try
+ {
+ if (first)
+ first = false;
+ else
+ state = iterate(state);
+ hasResult = condition(state);
+ if (hasResult)
+ {
+ result = resultSelector(state);
+ time = timeSelector(state);
+ }
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ if (hasResult)
+ self(time);
+ else
+ observer.OnCompleted();
+ });
+ });
+#endif
+ }
+
+ public virtual IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, DateTimeOffset> timeSelector)
+ {
+ return Generate_<TState, TResult>(initialState, condition, iterate, resultSelector, timeSelector, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, DateTimeOffset> timeSelector, IScheduler scheduler)
+ {
+ return Generate_<TState, TResult>(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
+ }
+
+ private static IObservable<TResult> Generate_<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, Func<TState, DateTimeOffset> timeSelector, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Generate<TState, TResult>(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
+#else
+ return new AnonymousObservable<TResult>(observer =>
+ {
+ var state = initialState;
+ var first = true;
+ var hasResult = false;
+ var result = default(TResult);
+ var time = default(DateTimeOffset);
+ return scheduler.Schedule(scheduler.Now, self =>
+ {
+ if (hasResult)
+ observer.OnNext(result);
+ try
+ {
+ if (first)
+ first = false;
+ else
+ state = iterate(state);
+ hasResult = condition(state);
+ if (hasResult)
+ {
+ result = resultSelector(state);
+ time = timeSelector(state);
+ }
+ }
+ catch (Exception exception)
+ {
+ observer.OnError(exception);
+ return;
+ }
+
+ if (hasResult)
+ self(time);
+ else
+ observer.OnCompleted();
+ });
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Interval +
+
+ public virtual IObservable<long> Interval(TimeSpan period)
+ {
+ return Timer_(period, period, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<long> Interval(TimeSpan period, IScheduler scheduler)
+ {
+ return Timer_(period, period, scheduler);
+ }
+
+ #endregion
+
+ #region + Sample +
+
+ public virtual IObservable<TSource> Sample<TSource>(IObservable<TSource> source, TimeSpan interval)
+ {
+ return Sample_<TSource>(source, interval, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> Sample<TSource>(IObservable<TSource> source, TimeSpan interval, IScheduler scheduler)
+ {
+ return Sample_<TSource>(source, interval, scheduler);
+ }
+
+ private static IObservable<TSource> Sample_<TSource>(IObservable<TSource> source, TimeSpan interval, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Sample<TSource>(source, interval, scheduler);
+#else
+ var sampler = Observable.Interval(interval, scheduler);
+ return Sample_<TSource, long>(source, sampler);
+#endif
+ }
+
+ public virtual IObservable<TSource> Sample<TSource, TSample>(IObservable<TSource> source, IObservable<TSample> sampler)
+ {
+ return Sample_<TSource, TSample>(source, sampler);
+ }
+
+ private static IObservable<TSource> Sample_<TSource, TSample>(IObservable<TSource> source, IObservable<TSample> sampler)
+ {
+#if !NO_PERF
+ return new Sample<TSource, TSample>(source, sampler);
+#else
+ return Combine(source, sampler, (IObserver<TSource> observer, IDisposable leftSubscription, IDisposable rightSubscription) =>
+ {
+ var value = default(Notification<TSource>);
+ var atEnd = false;
+ return new BinaryObserver<TSource, TSample>(
+ newValue =>
+ {
+ switch (newValue.Kind)
+ {
+ case NotificationKind.OnNext:
+ value = newValue;
+ break;
+ case NotificationKind.OnError:
+ newValue.Accept(observer);
+ break;
+ case NotificationKind.OnCompleted:
+ atEnd = true;
+ break;
+ }
+ },
+ _ =>
+ {
+ var myValue = value;
+ value = null;
+ if (myValue != null)
+ myValue.Accept(observer);
+ if (atEnd)
+ observer.OnCompleted();
+ });
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Skip +
+
+ public virtual IObservable<TSource> Skip<TSource>(IObservable<TSource> source, TimeSpan duration)
+ {
+ return Skip_<TSource>(source, duration, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> Skip<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ return Skip_<TSource>(source, duration, scheduler);
+ }
+
+ private static IObservable<TSource> Skip_<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+#if !NO_PERF
+ var skip = source as Skip<TSource>;
+ if (skip != null && skip._scheduler == scheduler)
+ return skip.Ω(duration);
+
+ return new Skip<TSource>(source, duration, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var open = false;
+
+ var t = scheduler.Schedule(duration, () => open = true);
+
+ var d = source.Subscribe(
+ x =>
+ {
+ if (open)
+ observer.OnNext(x);
+ },
+ observer.OnError,
+ observer.OnCompleted
+ );
+
+ return new CompositeDisposable(t, d);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + SkipLast +
+
+ public virtual IObservable<TSource> SkipLast<TSource>(IObservable<TSource> source, TimeSpan duration)
+ {
+ return SkipLast_<TSource>(source, duration, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> SkipLast<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ return SkipLast_<TSource>(source, duration, scheduler);
+ }
+
+ private static IObservable<TSource> SkipLast_<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new SkipLast<TSource>(source, duration, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var q = new Queue<System.Reactive.TimeInterval<TSource>>();
+
+ var swp = scheduler.AsStopwatchProvider();
+ var sw = swp != null ? swp.StartStopwatch() : new DefaultStopwatch();
+
+ return source.Subscribe(
+ x =>
+ {
+ var now = sw.Elapsed;
+ q.Enqueue(new System.Reactive.TimeInterval<TSource>(x, now));
+ while (q.Count > 0 && now - q.Peek().Interval >= duration)
+ observer.OnNext(q.Dequeue().Value);
+ },
+ observer.OnError,
+ () =>
+ {
+ var now = sw.Elapsed;
+ while (q.Count > 0 && now - q.Peek().Interval >= duration)
+ observer.OnNext(q.Dequeue().Value);
+ observer.OnCompleted();
+ }
+ );
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + SkipUntil +
+
+ public virtual IObservable<TSource> SkipUntil<TSource>(IObservable<TSource> source, DateTimeOffset startTime)
+ {
+ return SkipUntil_<TSource>(source, startTime, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> SkipUntil<TSource>(IObservable<TSource> source, DateTimeOffset startTime, IScheduler scheduler)
+ {
+ return SkipUntil_<TSource>(source, startTime, scheduler);
+ }
+
+ private static IObservable<TSource> SkipUntil_<TSource>(IObservable<TSource> source, DateTimeOffset startTime, IScheduler scheduler)
+ {
+#if !NO_PERF
+ var skipUntil = source as SkipUntil<TSource>;
+ if (skipUntil != null && skipUntil._scheduler == scheduler)
+ return skipUntil.Ω(startTime);
+
+ return new SkipUntil<TSource>(source, startTime, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var open = false;
+
+ var t = scheduler.Schedule(startTime, () => open = true);
+
+ var d = source.Subscribe(
+ x =>
+ {
+ if (open)
+ observer.OnNext(x);
+ },
+ observer.OnError,
+ observer.OnCompleted
+ );
+
+ return new CompositeDisposable(t, d);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Take +
+
+ public virtual IObservable<TSource> Take<TSource>(IObservable<TSource> source, TimeSpan duration)
+ {
+ return Take_<TSource>(source, duration, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> Take<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ return Take_<TSource>(source, duration, scheduler);
+ }
+
+ private static IObservable<TSource> Take_<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+#if !NO_PERF
+ var take = source as Take<TSource>;
+ if (take != null && take._scheduler == scheduler)
+ return take.Ω(duration);
+
+ return new Take<TSource>(source, duration, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var gate = new object();
+
+ var t = scheduler.Schedule(duration, () =>
+ {
+ lock (gate)
+ {
+ observer.OnCompleted();
+ }
+ });
+
+ var d = source.Synchronize(gate).Subscribe(observer);
+
+ return new CompositeDisposable(t, d);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + TakeLast +
+
+ public virtual IObservable<TSource> TakeLast<TSource>(IObservable<TSource> source, TimeSpan duration)
+ {
+ return TakeLast_<TSource>(source, duration, SchedulerDefaults.TimeBasedOperations, SchedulerDefaults.Iteration);
+ }
+
+ public virtual IObservable<TSource> TakeLast<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ return TakeLast_<TSource>(source, duration, scheduler, SchedulerDefaults.Iteration);
+ }
+
+ public virtual IObservable<TSource> TakeLast<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler timerScheduler, IScheduler loopScheduler)
+ {
+ return TakeLast_<TSource>(source, duration, timerScheduler, loopScheduler);
+ }
+
+ private static IObservable<TSource> TakeLast_<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler timerScheduler, IScheduler loopScheduler)
+ {
+#if !NO_PERF
+ return new TakeLast<TSource>(source, duration, timerScheduler, loopScheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var q = new Queue<System.Reactive.TimeInterval<TSource>>();
+
+ var swp = timerScheduler.AsStopwatchProvider();
+ var sw = swp != null ? swp.StartStopwatch() : new DefaultStopwatch();
+
+ var trim = new Action<TimeSpan>(now =>
+ {
+ while (q.Count > 0 && now - q.Peek().Interval >= duration)
+ q.Dequeue();
+ });
+
+ var g = new CompositeDisposable();
+
+ g.Add(source.Subscribe(
+ x =>
+ {
+ var now = sw.Elapsed;
+
+ q.Enqueue(new System.Reactive.TimeInterval<TSource>(x, now));
+ trim(now);
+ },
+ observer.OnError,
+ () =>
+ {
+ var now = sw.Elapsed;
+ trim(now);
+
+ g.Add(loopScheduler.Schedule(rec =>
+ {
+ if (q.Count > 0)
+ {
+ observer.OnNext(q.Dequeue().Value);
+ rec();
+ }
+ else
+ {
+ observer.OnCompleted();
+ }
+ }));
+ }
+ ));
+
+ return g;
+ });
+#endif
+ }
+
+ public virtual IObservable<IList<TSource>> TakeLastBuffer<TSource>(IObservable<TSource> source, TimeSpan duration)
+ {
+ return TakeLastBuffer_<TSource>(source, duration, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<IList<TSource>> TakeLastBuffer<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+ return TakeLastBuffer_<TSource>(source, duration, scheduler);
+ }
+
+ private static IObservable<IList<TSource>> TakeLastBuffer_<TSource>(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new TakeLastBuffer<TSource>(source, duration, scheduler);
+#else
+ return new AnonymousObservable<IList<TSource>>(observer =>
+ {
+ var q = new Queue<System.Reactive.TimeInterval<TSource>>();
+
+ var swp = scheduler.AsStopwatchProvider();
+ var sw = swp != null ? swp.StartStopwatch() : new DefaultStopwatch();
+
+ return source.Subscribe(
+ x =>
+ {
+ var now = sw.Elapsed;
+
+ q.Enqueue(new System.Reactive.TimeInterval<TSource>(x, now));
+ while (q.Count > 0 && now - q.Peek().Interval >= duration)
+ q.Dequeue();
+ },
+ observer.OnError,
+ () =>
+ {
+ var now = sw.Elapsed;
+
+ var res = new List<TSource>();
+ while (q.Count > 0)
+ {
+ var next = q.Dequeue();
+ if (now - next.Interval <= duration)
+ res.Add(next.Value);
+ }
+
+ observer.OnNext(res);
+ observer.OnCompleted();
+ }
+ );
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + TakeUntil +
+
+ public virtual IObservable<TSource> TakeUntil<TSource>(IObservable<TSource> source, DateTimeOffset endTime)
+ {
+ return TakeUntil_<TSource>(source, endTime, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> TakeUntil<TSource>(IObservable<TSource> source, DateTimeOffset endTime, IScheduler scheduler)
+ {
+ return TakeUntil_<TSource>(source, endTime, scheduler);
+ }
+
+ private static IObservable<TSource> TakeUntil_<TSource>(IObservable<TSource> source, DateTimeOffset endTime, IScheduler scheduler)
+ {
+#if !NO_PERF
+ var takeUntil = source as TakeUntil<TSource>;
+ if (takeUntil != null && takeUntil._scheduler == scheduler)
+ return takeUntil.Ω(endTime);
+
+ return new TakeUntil<TSource>(source, endTime, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var gate = new object();
+
+ var t = scheduler.Schedule(endTime, () =>
+ {
+ lock (gate)
+ {
+ observer.OnCompleted();
+ }
+ });
+
+ var d = source.Synchronize(gate).Subscribe(observer);
+
+ return new CompositeDisposable(t, d);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Throttle +
+
+ public virtual IObservable<TSource> Throttle<TSource>(IObservable<TSource> source, TimeSpan dueTime)
+ {
+ return Throttle_<TSource>(source, dueTime, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> Throttle<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ return Throttle_<TSource>(source, dueTime, scheduler);
+ }
+
+ private static IObservable<TSource> Throttle_<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Throttle<TSource>(source, dueTime, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var gate = new object();
+ var value = default(TSource);
+ var hasValue = false;
+ var cancelable = new SerialDisposable();
+ var id = 0UL;
+
+ var subscription = source.Subscribe(x =>
+ {
+ ulong currentid;
+ lock (gate)
+ {
+ hasValue = true;
+ value = x;
+ id = unchecked(id + 1);
+ currentid = id;
+ }
+ var d = new SingleAssignmentDisposable();
+ cancelable.Disposable = d;
+ d.Disposable = scheduler.Schedule(dueTime, () =>
+ {
+ lock (gate)
+ {
+ if (hasValue && id == currentid)
+ observer.OnNext(value);
+ hasValue = false;
+ }
+ });
+ },
+ exception =>
+ {
+ cancelable.Dispose();
+
+ lock (gate)
+ {
+ observer.OnError(exception);
+ hasValue = false;
+ id = unchecked(id + 1);
+ }
+ },
+ () =>
+ {
+ cancelable.Dispose();
+
+ lock (gate)
+ {
+ if (hasValue)
+ observer.OnNext(value);
+ observer.OnCompleted();
+ hasValue = false;
+ id = unchecked(id + 1);
+ }
+ });
+
+ return new CompositeDisposable(subscription, cancelable);
+ });
+#endif
+ }
+
+ public virtual IObservable<TSource> Throttle<TSource, TThrottle>(IObservable<TSource> source, Func<TSource, IObservable<TThrottle>> throttleDurationSelector)
+ {
+#if !NO_PERF
+ return new Throttle<TSource, TThrottle>(source, throttleDurationSelector);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var gate = new object();
+ var value = default(TSource);
+ var hasValue = false;
+ var cancelable = new SerialDisposable();
+ var id = 0UL;
+
+ var subscription = source.Subscribe(
+ x =>
+ {
+ var throttle = default(IObservable<TThrottle>);
+ try
+ {
+ throttle = throttleDurationSelector(x);
+ }
+ catch (Exception error)
+ {
+ lock (gate)
+ observer.OnError(error);
+
+ return;
+ }
+
+ ulong currentid;
+ lock (gate)
+ {
+ hasValue = true;
+ value = x;
+ id = unchecked(id + 1);
+ currentid = id;
+ }
+
+ var d = new SingleAssignmentDisposable();
+ cancelable.Disposable = d;
+ d.Disposable = throttle.Subscribe(
+ _ =>
+ {
+ lock (gate)
+ {
+ if (hasValue && id == currentid)
+ observer.OnNext(value);
+
+ hasValue = false;
+ d.Dispose();
+ }
+ },
+ exception =>
+ {
+ lock (gate)
+ {
+ observer.OnError(exception);
+ }
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ if (hasValue && id == currentid)
+ observer.OnNext(value);
+
+ hasValue = false;
+ d.Dispose();
+ }
+ }
+ );
+ },
+ exception =>
+ {
+ cancelable.Dispose();
+
+ lock (gate)
+ {
+ observer.OnError(exception);
+ hasValue = false;
+ id = unchecked(id + 1);
+ }
+ },
+ () =>
+ {
+ cancelable.Dispose();
+
+ lock (gate)
+ {
+ if (hasValue)
+ observer.OnNext(value);
+ observer.OnCompleted();
+ hasValue = false;
+ id = unchecked(id + 1);
+ }
+ });
+
+ return new CompositeDisposable(subscription, cancelable);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + TimeInterval +
+
+ public virtual IObservable<System.Reactive.TimeInterval<TSource>> TimeInterval<TSource>(IObservable<TSource> source)
+ {
+ return TimeInterval_<TSource>(source, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<System.Reactive.TimeInterval<TSource>> TimeInterval<TSource>(IObservable<TSource> source, IScheduler scheduler)
+ {
+ return TimeInterval_<TSource>(source, scheduler);
+ }
+
+#if !NO_PERF
+ private static IObservable<System.Reactive.TimeInterval<TSource>> TimeInterval_<TSource>(IObservable<TSource> source, IScheduler scheduler)
+ {
+ return new TimeInterval<TSource>(source, scheduler);
+ }
+#else
+ private IObservable<System.Reactive.TimeInterval<TSource>> TimeInterval_<TSource>(IObservable<TSource> source, IScheduler scheduler)
+ {
+ return Defer(() =>
+ {
+ var last = scheduler.Now;
+ return source.Select(x =>
+ {
+ var now = scheduler.Now;
+ var span = now.Subtract(last);
+ last = now;
+ return new System.Reactive.TimeInterval<TSource>(x, span);
+ });
+ });
+ }
+#endif
+
+ #endregion
+
+ #region + Timeout +
+
+ #region TimeSpan
+
+ public virtual IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, TimeSpan dueTime)
+ {
+ return Timeout_<TSource>(source, dueTime, Observable.Throw<TSource>(new TimeoutException()), SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
+ {
+ return Timeout_<TSource>(source, dueTime, Observable.Throw<TSource>(new TimeoutException()), scheduler);
+ }
+
+ public virtual IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, TimeSpan dueTime, IObservable<TSource> other)
+ {
+ return Timeout_<TSource>(source, dueTime, other, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, TimeSpan dueTime, IObservable<TSource> other, IScheduler scheduler)
+ {
+ return Timeout_<TSource>(source, dueTime, other, scheduler);
+ }
+
+ private static IObservable<TSource> Timeout_<TSource>(IObservable<TSource> source, TimeSpan dueTime, IObservable<TSource> other, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Timeout<TSource>(source, dueTime, other, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var subscription = new SerialDisposable();
+ var timer = new SerialDisposable();
+ var original = new SingleAssignmentDisposable();
+
+ subscription.Disposable = original;
+
+ var gate = new object();
+ var id = 0UL;
+ var switched = false;
+
+ Action createTimer = () =>
+ {
+ var myid = id;
+ timer.Disposable = scheduler.Schedule(dueTime, () =>
+ {
+ var timerWins = false;
+
+ lock (gate)
+ {
+ switched = (id == myid);
+ timerWins = switched;
+ }
+
+ if (timerWins)
+ subscription.Disposable = other.Subscribe(observer);
+ });
+ };
+
+ createTimer();
+
+ original.Disposable = source.Subscribe(
+ x =>
+ {
+ var onNextWins = false;
+
+ lock (gate)
+ {
+ onNextWins = !switched;
+ if (onNextWins)
+ {
+ id = unchecked(id + 1);
+ }
+ }
+
+ if (onNextWins)
+ {
+ observer.OnNext(x);
+ createTimer();
+ }
+ },
+ exception =>
+ {
+ var onErrorWins = false;
+
+ lock (gate)
+ {
+ onErrorWins = !switched;
+ if (onErrorWins)
+ {
+ id = unchecked(id + 1);
+ }
+ }
+
+ if (onErrorWins)
+ observer.OnError(exception);
+ },
+ () =>
+ {
+ var onCompletedWins = false;
+
+ lock (gate)
+ {
+ onCompletedWins = !switched;
+ if (onCompletedWins)
+ {
+ id = unchecked(id + 1);
+ }
+ }
+
+ if (onCompletedWins)
+ observer.OnCompleted();
+ });
+
+ return new CompositeDisposable(subscription, timer);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region DateTimeOffset
+
+ public virtual IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, DateTimeOffset dueTime)
+ {
+ return Timeout_<TSource>(source, dueTime, Observable.Throw<TSource>(new TimeoutException()), SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
+ {
+ return Timeout_<TSource>(source, dueTime, Observable.Throw<TSource>(new TimeoutException()), scheduler);
+ }
+
+ public virtual IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IObservable<TSource> other)
+ {
+ return Timeout_<TSource>(source, dueTime, other, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<TSource> Timeout<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IObservable<TSource> other, IScheduler scheduler)
+ {
+ return Timeout_<TSource>(source, dueTime, other, scheduler);
+ }
+
+ private static IObservable<TSource> Timeout_<TSource>(IObservable<TSource> source, DateTimeOffset dueTime, IObservable<TSource> other, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Timeout<TSource>(source, dueTime, other, scheduler);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var subscription = new SerialDisposable();
+ var original = new SingleAssignmentDisposable();
+
+ subscription.Disposable = original;
+
+ var gate = new object();
+ var switched = false;
+
+ var timer = scheduler.Schedule(dueTime, () =>
+ {
+ var timerWins = false;
+
+ lock (gate)
+ {
+ timerWins = !switched;
+ switched = true;
+ }
+
+ if (timerWins)
+ subscription.Disposable = other.Subscribe(observer);
+ });
+
+ original.Disposable = source.Subscribe(
+ x =>
+ {
+ lock (gate)
+ {
+ if (!switched)
+ observer.OnNext(x);
+ }
+ },
+ exception =>
+ {
+ var onErrorWins = false;
+
+ lock (gate)
+ {
+ onErrorWins = !switched;
+ switched = true;
+ }
+
+ if (onErrorWins)
+ observer.OnError(exception);
+ },
+ () =>
+ {
+ var onCompletedWins = false;
+
+ lock (gate)
+ {
+ onCompletedWins = !switched;
+ switched = true;
+ }
+
+ if (onCompletedWins)
+ observer.OnCompleted();
+ });
+
+ return new CompositeDisposable(subscription, timer);
+ });
+#endif
+ }
+
+ #endregion
+
+ #region Duration selector
+
+ public virtual IObservable<TSource> Timeout<TSource, TTimeout>(IObservable<TSource> source, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector)
+ {
+ return Timeout_<TSource, TTimeout>(source, Observable.Never<TTimeout>(), timeoutDurationSelector, Observable.Throw<TSource>(new TimeoutException()));
+ }
+
+ public virtual IObservable<TSource> Timeout<TSource, TTimeout>(IObservable<TSource> source, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector, IObservable<TSource> other)
+ {
+ return Timeout_<TSource, TTimeout>(source, Observable.Never<TTimeout>(), timeoutDurationSelector, other);
+ }
+
+ public virtual IObservable<TSource> Timeout<TSource, TTimeout>(IObservable<TSource> source, IObservable<TTimeout> firstTimeout, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector)
+ {
+ return Timeout_<TSource, TTimeout>(source, firstTimeout, timeoutDurationSelector, Observable.Throw<TSource>(new TimeoutException()));
+ }
+
+ public virtual IObservable<TSource> Timeout<TSource, TTimeout>(IObservable<TSource> source, IObservable<TTimeout> firstTimeout, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector, IObservable<TSource> other)
+ {
+ return Timeout_<TSource, TTimeout>(source, firstTimeout, timeoutDurationSelector, other);
+ }
+
+ private static IObservable<TSource> Timeout_<TSource, TTimeout>(IObservable<TSource> source, IObservable<TTimeout> firstTimeout, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector, IObservable<TSource> other)
+ {
+#if !NO_PERF
+ return new Timeout<TSource, TTimeout>(source, firstTimeout, timeoutDurationSelector, other);
+#else
+ return new AnonymousObservable<TSource>(observer =>
+ {
+ var subscription = new SerialDisposable();
+ var timer = new SerialDisposable();
+ var original = new SingleAssignmentDisposable();
+
+ subscription.Disposable = original;
+
+ var gate = new object();
+ var id = 0UL;
+ var switched = false;
+
+ Action<IObservable<TTimeout>> setTimer = timeout =>
+ {
+ var myid = id;
+
+ Func<bool> timerWins = () =>
+ {
+ var res = false;
+
+ lock (gate)
+ {
+ switched = (id == myid);
+ res = switched;
+ }
+
+ return res;
+ };
+
+ var d = new SingleAssignmentDisposable();
+ timer.Disposable = d;
+ d.Disposable = timeout.Subscribe(
+ _ =>
+ {
+ if (timerWins())
+ subscription.Disposable = other.Subscribe(observer);
+
+ d.Dispose();
+ },
+ error =>
+ {
+ if (timerWins())
+ observer.OnError(error);
+ },
+ () =>
+ {
+ if (timerWins())
+ subscription.Disposable = other.Subscribe(observer);
+ }
+ );
+ };
+
+ setTimer(firstTimeout);
+
+ Func<bool> observerWins = () =>
+ {
+ var res = false;
+
+ lock (gate)
+ {
+ res = !switched;
+ if (res)
+ {
+ id = unchecked(id + 1);
+ }
+ }
+
+ return res;
+ };
+
+ original.Disposable = source.Subscribe(
+ x =>
+ {
+ if (observerWins())
+ {
+ observer.OnNext(x);
+
+ var timeout = default(IObservable<TTimeout>);
+ try
+ {
+ timeout = timeoutDurationSelector(x);
+ }
+ catch (Exception error)
+ {
+ observer.OnError(error);
+ return;
+ }
+
+ setTimer(timeout);
+ }
+ },
+ exception =>
+ {
+ if (observerWins())
+ observer.OnError(exception);
+ },
+ () =>
+ {
+ if (observerWins())
+ observer.OnCompleted();
+ }
+ );
+
+ return new CompositeDisposable(subscription, timer);
+ });
+#endif
+ }
+
+ #endregion
+
+ #endregion
+
+ #region + Timer +
+
+ public virtual IObservable<long> Timer(TimeSpan dueTime)
+ {
+ return Timer_(dueTime, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<long> Timer(DateTimeOffset dueTime)
+ {
+ return Timer_(dueTime, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<long> Timer(TimeSpan dueTime, TimeSpan period)
+ {
+ return Timer_(dueTime, period, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<long> Timer(DateTimeOffset dueTime, TimeSpan period)
+ {
+ return Timer_(dueTime, period, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<long> Timer(TimeSpan dueTime, IScheduler scheduler)
+ {
+ return Timer_(dueTime, scheduler);
+ }
+
+ public virtual IObservable<long> Timer(DateTimeOffset dueTime, IScheduler scheduler)
+ {
+ return Timer_(dueTime, scheduler);
+ }
+
+ public virtual IObservable<long> Timer(TimeSpan dueTime, TimeSpan period, IScheduler scheduler)
+ {
+ return Timer_(dueTime, period, scheduler);
+ }
+
+ public virtual IObservable<long> Timer(DateTimeOffset dueTime, TimeSpan period, IScheduler scheduler)
+ {
+ return Timer_(dueTime, period, scheduler);
+ }
+
+ private static IObservable<long> Timer_(TimeSpan dueTime, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Timer(dueTime, null, scheduler);
+#else
+ var d = Normalize(dueTime);
+
+ return new AnonymousObservable<long>(observer =>
+ scheduler.Schedule(d, () =>
+ {
+ observer.OnNext(0);
+ observer.OnCompleted();
+ }));
+#endif
+ }
+
+#if !NO_PERF
+ private static IObservable<long> Timer_(TimeSpan dueTime, TimeSpan period, IScheduler scheduler)
+ {
+ return new Timer(dueTime, period, scheduler);
+ }
+#else
+ private IObservable<long> Timer_(TimeSpan dueTime, TimeSpan period, IScheduler scheduler)
+ {
+ var p = Normalize(period);
+
+ return Defer(() => Timer(scheduler.Now + dueTime, p, scheduler));
+ }
+#endif
+
+ private static IObservable<long> Timer_(DateTimeOffset dueTime, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Timer(dueTime, null, scheduler);
+#else
+ return new AnonymousObservable<long>(observer =>
+ scheduler.Schedule(dueTime, () =>
+ {
+ observer.OnNext(0);
+ observer.OnCompleted();
+ }));
+#endif
+ }
+
+ private static IObservable<long> Timer_(DateTimeOffset dueTime, TimeSpan period, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Timer(dueTime, period, scheduler);
+#else
+ var p = Normalize(period);
+
+ return new AnonymousObservable<long>(observer =>
+ {
+ var d = dueTime;
+ var count = 0L;
+
+ return scheduler.Schedule(d, self =>
+ {
+ if (p > TimeSpan.Zero)
+ {
+ var now = scheduler.Now;
+ d = d + p;
+ if (d <= now)
+ d = now + p;
+ }
+
+ observer.OnNext(count);
+ count = unchecked(count + 1);
+ self(d);
+ });
+ });
+#endif
+ }
+
+ #endregion
+
+ #region + Timestamp +
+
+ public virtual IObservable<Timestamped<TSource>> Timestamp<TSource>(IObservable<TSource> source)
+ {
+ return Timestamp_<TSource>(source, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<Timestamped<TSource>> Timestamp<TSource>(IObservable<TSource> source, IScheduler scheduler)
+ {
+ return Timestamp_<TSource>(source, scheduler);
+ }
+
+ private static IObservable<Timestamped<TSource>> Timestamp_<TSource>(IObservable<TSource> source, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Timestamp<TSource>(source, scheduler);
+#else
+ return source.Select(x => new Timestamped<TSource>(x, scheduler.Now));
+#endif
+ }
+
+ #endregion
+
+ #region + Window +
+
+ #region TimeSpan only
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan)
+ {
+ return Window_<TSource>(source, timeSpan, timeSpan, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan, IScheduler scheduler)
+ {
+ return Window_<TSource>(source, timeSpan, timeSpan, scheduler);
+ }
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift)
+ {
+ return Window_<TSource>(source, timeSpan, timeShift, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler)
+ {
+ return Window_<TSource>(source, timeSpan, timeShift, scheduler);
+ }
+
+ private static IObservable<IObservable<TSource>> Window_<TSource>(IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Window<TSource>(source, timeSpan, timeShift, scheduler);
+#else
+ return new AnonymousObservable<IObservable<TSource>>(observer =>
+ {
+ var totalTime = TimeSpan.Zero;
+ var nextShift = timeShift;
+ var nextSpan = timeSpan;
+
+ var gate = new object();
+ var q = new Queue<ISubject<TSource>>();
+
+ var timerD = new SerialDisposable();
+ var groupDisposable = new CompositeDisposable(2) { timerD };
+ var refCountDisposable = new RefCountDisposable(groupDisposable);
+
+ var createTimer = default(Action);
+ createTimer = () =>
+ {
+ var m = new SingleAssignmentDisposable();
+ timerD.Disposable = m;
+
+ var isSpan = false;
+ var isShift = false;
+ if (nextSpan == nextShift)
+ {
+ isSpan = true;
+ isShift = true;
+ }
+ else if (nextSpan < nextShift)
+ isSpan = true;
+ else
+ isShift = true;
+
+ var newTotalTime = isSpan ? nextSpan : nextShift;
+ var ts = newTotalTime - totalTime;
+ totalTime = newTotalTime;
+
+ if (isSpan)
+ nextSpan += timeShift;
+ if (isShift)
+ nextShift += timeShift;
+
+ m.Disposable = scheduler.Schedule(ts, () =>
+ {
+ lock (gate)
+ {
+ if (isShift)
+ {
+ var s = new Subject<TSource>();
+ q.Enqueue(s);
+ observer.OnNext(s.AddRef(refCountDisposable));
+ }
+ if (isSpan)
+ {
+ var s = q.Dequeue();
+ s.OnCompleted();
+ }
+ }
+
+ createTimer();
+ });
+ };
+
+ q.Enqueue(new Subject<TSource>());
+ observer.OnNext(q.Peek().AddRef(refCountDisposable));
+ createTimer();
+
+ groupDisposable.Add(source.Subscribe(
+ x =>
+ {
+ lock (gate)
+ {
+ foreach (var s in q)
+ s.OnNext(x);
+ }
+ },
+ exception =>
+ {
+ lock (gate)
+ {
+ foreach (var s in q)
+ s.OnError(exception);
+ observer.OnError(exception);
+ }
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ foreach (var s in q)
+ s.OnCompleted();
+ observer.OnCompleted();
+ }
+ }
+ ));
+
+ return refCountDisposable;
+ });
+#endif
+ }
+
+ #endregion
+
+ #region TimeSpan + int
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan, int count)
+ {
+ return Window_<TSource>(source, timeSpan, count, SchedulerDefaults.TimeBasedOperations);
+ }
+
+ public virtual IObservable<IObservable<TSource>> Window<TSource>(IObservable<TSource> source, TimeSpan timeSpan, int count, IScheduler scheduler)
+ {
+ return Window_<TSource>(source, timeSpan, count, scheduler);
+ }
+
+ private static IObservable<IObservable<TSource>> Window_<TSource>(IObservable<TSource> source, TimeSpan timeSpan, int count, IScheduler scheduler)
+ {
+#if !NO_PERF
+ return new Window<TSource>(source, timeSpan, count, scheduler);
+#else
+ return new AnonymousObservable<IObservable<TSource>>(observer =>
+ {
+ var gate = new object();
+ var s = default(ISubject<TSource>);
+ var n = 0;
+ var windowId = 0;
+
+ var timerD = new SerialDisposable();
+ var groupDisposable = new CompositeDisposable(2) { timerD };
+ var refCountDisposable = new RefCountDisposable(groupDisposable);
+
+ var createTimer = default(Action<int>);
+ createTimer = id =>
+ {
+ var m = new SingleAssignmentDisposable();
+ timerD.Disposable = m;
+
+ m.Disposable = scheduler.Schedule(timeSpan, () =>
+ {
+ var newId = 0;
+ lock (gate)
+ {
+ if (id != windowId)
+ return;
+ n = 0;
+ newId = ++windowId;
+
+ s.OnCompleted();
+ s = new Subject<TSource>();
+ observer.OnNext(s.AddRef(refCountDisposable));
+ }
+
+ createTimer(newId);
+ });
+ };
+
+ s = new Subject<TSource>();
+ observer.OnNext(s.AddRef(refCountDisposable));
+ createTimer(0);
+
+ groupDisposable.Add(source.Subscribe(
+ x =>
+ {
+ var newWindow = false;
+ var newId = 0;
+
+ lock (gate)
+ {
+ s.OnNext(x);
+
+ n++;
+ if (n == count)
+ {
+ newWindow = true;
+ n = 0;
+ newId = ++windowId;
+
+ s.OnCompleted();
+ s = new Subject<TSource>();
+ observer.OnNext(s.AddRef(refCountDisposable));
+ }
+ }
+
+ if (newWindow)
+ createTimer(newId);
+ },
+ exception =>
+ {
+ lock (gate)
+ {
+ s.OnError(exception);
+ observer.OnError(exception);
+ }
+ },
+ () =>
+ {
+ lock (gate)
+ {
+ s.OnCompleted();
+ observer.OnCompleted();
+ }
+ }
+ ));
+
+ return refCountDisposable;
+ });
+#endif
+ }
+
+ #endregion
+
+ #endregion
+
+ #region |> Helpers <|
+
+#if NO_PERF
+ private static TimeSpan Normalize(TimeSpan timeSpan)
+ {
+ if (timeSpan.CompareTo(TimeSpan.Zero) < 0)
+ return TimeSpan.Zero;
+ return timeSpan;
+ }
+#endif
+
+ #endregion
+ }
+}
diff --git a/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage_.cs b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage_.cs
new file mode 100644
index 0000000..5ea20e7
--- /dev/null
+++ b/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage_.cs
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+namespace System.Reactive.Linq
+{
+ internal partial class QueryLanguage : IQueryLanguage
+ {
+ }
+}