Browse Source

Document AsyncEnumerableEx methods

akarnokd 5 years ago
parent
commit
a2ff356228
30 changed files with 860 additions and 0 deletions
  1. 4 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs
  2. 22 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Amb.cs
  3. 19 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Buffer.cs
  4. 49 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Catch.cs
  5. 21 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Concat.cs
  6. 25 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Defer.cs
  7. 63 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Distinct.cs
  8. 72 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/DistinctUntilChanged.cs
  9. 129 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Do.cs
  10. 21 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Expand.cs
  11. 16 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Finally.cs
  12. 11 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Generate.cs
  13. 7 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/IgnoreElements.cs
  14. 8 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/IsEmpty.cs
  15. 10 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Max.cs
  16. 69 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxBy.cs
  17. 21 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Merge.cs
  18. 10 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Min.cs
  19. 69 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinBy.cs
  20. 5 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Never.cs
  21. 22 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/OnErrorResumeNext.cs
  22. 22 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Repeat.cs
  23. 16 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Retry.cs
  24. 6 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Return.cs
  25. 60 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Scan.cs
  26. 9 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/SelectMany.cs
  27. 8 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/StartWith.cs
  28. 7 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Throw.cs
  29. 27 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Timeout.cs
  30. 32 0
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Using.cs

+ 4 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs

@@ -4,6 +4,10 @@
 
 namespace System.Linq
 {
+    /// <summary>
+    /// Provides an additional set of extension methods for writing in-memory queries, transformations of async-enumerable sequences.
+    /// </summary>
+    /// <seealso cref="AsyncEnumerable"/>
     public static partial class AsyncEnumerableEx
     {
     }

+ 22 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Amb.cs

@@ -10,6 +10,14 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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>
         public static IAsyncEnumerable<TSource> Amb<TSource>(this IAsyncEnumerable<TSource> first, IAsyncEnumerable<TSource> second)
         {
             if (first == null)
@@ -140,6 +148,13 @@ namespace System.Linq
             }
         }
 
+        /// <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>
         public static IAsyncEnumerable<TSource> Amb<TSource>(params IAsyncEnumerable<TSource>[] sources)
         {
             if (sources == null)
@@ -243,6 +258,13 @@ namespace System.Linq
             }
         }
 
+        /// <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>
         public static IAsyncEnumerable<TSource> Amb<TSource>(this IEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)

+ 19 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Buffer.cs

@@ -10,6 +10,15 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 IAsyncEnumerable<IList<TSource>> Buffer<TSource>(this IAsyncEnumerable<TSource> source, int count)
         {
             if (source == null)
@@ -42,6 +51,16 @@ namespace System.Linq
             }
         }
 
+        /// <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 IAsyncEnumerable<IList<TSource>> Buffer<TSource>(this IAsyncEnumerable<TSource> source, int count, int skip)
         {
             if (source == null)

+ 49 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Catch.cs

@@ -16,6 +16,15 @@ namespace System.Linq
         //
         //         catch (TException ex) when(!(ex is OperationCanceledException oce && oce.CancellationToken == cancellationToken))
 
+        /// <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="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 IAsyncEnumerable<TSource> Catch<TSource, TException>(this IAsyncEnumerable<TSource> source, Func<TException, IAsyncEnumerable<TSource>> handler)
             where TException : Exception
         {
@@ -70,6 +79,15 @@ namespace System.Linq
             }
         }
 
+        /// <summary>
+        /// Continues an observable sequence that is terminated by an exception of the specified type with the observable sequence produced asynchronously 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="Exception"/>.</typeparam>
+        /// <param name="source">Source sequence.</param>
+        /// <param name="handler">Exception handler function, producing another observable sequence asynchronously.</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 IAsyncEnumerable<TSource> Catch<TSource, TException>(this IAsyncEnumerable<TSource> source, Func<TException, ValueTask<IAsyncEnumerable<TSource>>> handler)
             where TException : Exception
         {
@@ -125,6 +143,15 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <summary>
+        /// Continues an observable sequence that is terminated by an exception of the specified type with the observable sequence produced asynchronously (cancellable) 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="Exception"/>.</typeparam>
+        /// <param name="source">Source sequence.</param>
+        /// <param name="handler">Exception handler function, producing another observable sequence asynchronously while supporting cancellation.</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 IAsyncEnumerable<TSource> Catch<TSource, TException>(this IAsyncEnumerable<TSource> source, Func<TException, CancellationToken, ValueTask<IAsyncEnumerable<TSource>>> handler)
             where TException : Exception
         {
@@ -180,6 +207,13 @@ namespace System.Linq
         }
 #endif
 
+        /// <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 IAsyncEnumerable<TSource> Catch<TSource>(this IEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
@@ -188,6 +222,13 @@ namespace System.Linq
             return CatchCore(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 IAsyncEnumerable<TSource> Catch<TSource>(params IAsyncEnumerable<TSource>[] sources)
         {
             if (sources == null)
@@ -196,6 +237,14 @@ namespace System.Linq
             return CatchCore(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 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 IAsyncEnumerable<TSource> Catch<TSource>(this IAsyncEnumerable<TSource> first, IAsyncEnumerable<TSource> second)
         {
             if (first == null)

+ 21 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Concat.cs

@@ -10,6 +10,13 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 IAsyncEnumerable<TSource> Concat<TSource>(this IAsyncEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
@@ -29,6 +36,13 @@ namespace System.Linq
             }
         }
 
+        /// <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 IAsyncEnumerable<TSource> Concat<TSource>(this IEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
@@ -48,6 +62,13 @@ namespace System.Linq
             }
         }
 
+        /// <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 IAsyncEnumerable<TSource> Concat<TSource>(params IAsyncEnumerable<TSource>[] sources)
         {
             if (sources == null)

+ 25 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Defer.cs

@@ -10,6 +10,13 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <summary>
+        /// Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
+        /// </summary>
+        /// <typeparam name="TSource">The type of the elements in the sequence returned by the factory function, and in the resulting sequence.</typeparam>
+        /// <param name="factory">The async-enumerable factory function to invoke for each consumer that starts enumerating the resulting asynchronous sequence.</param>
+        /// <returns>An observable sequence whose observers trigger an invocation of the given observable factory function.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="factory"/> is null.</exception>
         public static IAsyncEnumerable<TSource> Defer<TSource>(Func<IAsyncEnumerable<TSource>> factory)
         {
             if (factory == null)
@@ -26,6 +33,14 @@ namespace System.Linq
             }
         }
 
+        /// <summary>
+        /// Returns an observable sequence that starts the specified asynchronous factory function whenever a new observer subscribes.
+        /// </summary>
+        /// <typeparam name="TSource">The type of the elements in the sequence returned by the factory function, and in the resulting sequence.</typeparam>
+        /// <param name="factory">Asynchronous factory function to start for each consumer that starts enumerating the resulting asynchronous sequence.</param>
+        /// <returns>An observable sequence whose observers trigger the given asynchronous observable factory function to be started.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="factory"/> 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 IAsyncEnumerable<TSource> Defer<TSource>(Func<Task<IAsyncEnumerable<TSource>>> factory)
         {
             if (factory == null)
@@ -43,6 +58,16 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <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="TSource">The type of the elements in the sequence returned by the factory function, and in the resulting sequence.</typeparam>
+        /// <param name="factory">Asynchronous factory function, supporting cancellation, to start for each consumer that starts enumerating the resulting asynchronous sequence.</param>
+        /// <returns>An observable sequence whose observers trigger the given asynchronous observable factory function to be started.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="factory"/> 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 IAsyncEnumerable<TSource> Defer<TSource>(Func<CancellationToken, Task<IAsyncEnumerable<TSource>>> factory)
         {
             if (factory == null)

+ 63 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Distinct.cs

@@ -10,6 +10,16 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 IAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
         {
             if (source == null)
@@ -20,6 +30,17 @@ namespace System.Linq
             return DistinctCore(source, keySelector, comparer: null);
         }
 
+        /// <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 IAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? comparer)
         {
             if (source == null)
@@ -30,6 +51,16 @@ namespace System.Linq
             return DistinctCore(source, keySelector, comparer);
         }
 
+        /// <summary>
+        /// Returns an observable sequence that contains only distinct elements according to the asynchronous 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">An asynchronous 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 IAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector)
         {
             if (source == null)
@@ -41,6 +72,16 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <summary>
+        /// Returns an observable sequence that contains only distinct elements according to the asynchronous (cancellable) 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">An asynchronous (cancellable) 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 IAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector)
         {
             if (source == null)
@@ -52,6 +93,17 @@ namespace System.Linq
         }
 #endif
 
+        /// <summary>
+        /// Returns an observable sequence that contains only distinct elements according to the asynchronous 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">An asynchronous 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 IAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, IEqualityComparer<TKey>? comparer)
         {
             if (source == null)
@@ -63,6 +115,17 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <summary>
+        /// Returns an observable sequence that contains only distinct elements according to the asynchronous (cancellable) 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">An asynchronous (cancellable) 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 IAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector, IEqualityComparer<TKey>? comparer)
         {
             if (source == null)

+ 72 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/DistinctUntilChanged.cs

@@ -10,6 +10,13 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 IAsyncEnumerable<TSource> DistinctUntilChanged<TSource>(this IAsyncEnumerable<TSource> source)
         {
             if (source == null)
@@ -18,6 +25,14 @@ namespace System.Linq
             return DistinctUntilChangedCore(source, comparer: null);
         }
 
+        /// <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 IAsyncEnumerable<TSource> DistinctUntilChanged<TSource>(this IAsyncEnumerable<TSource> source, IEqualityComparer<TSource>? comparer)
         {
             if (source == null)
@@ -26,6 +41,15 @@ namespace System.Linq
             return DistinctUntilChangedCore(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 IAsyncEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
         {
             if (source == null)
@@ -36,6 +60,16 @@ namespace System.Linq
             return DistinctUntilChangedCore(source, keySelector, comparer: null);
         }
 
+        /// <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 IAsyncEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? comparer)
         {
             if (source == null)
@@ -46,6 +80,15 @@ namespace System.Linq
             return DistinctUntilChangedCore(source, keySelector, comparer);
         }
 
+        /// <summary>
+        /// Returns an observable sequence that contains only distinct contiguous elements according to the asynchronous 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 asynchronously.</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 IAsyncEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector)
         {
             if (source == null)
@@ -57,6 +100,15 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <summary>
+        /// Returns an observable sequence that contains only distinct contiguous elements according to the asynchronous and cancellable 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 asynchronously while supporting cancellation.</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 IAsyncEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector)
         {
             if (source == null)
@@ -68,6 +120,16 @@ namespace System.Linq
         }
 #endif
 
+        /// <summary>
+        /// Returns an observable sequence that contains only distinct contiguous elements according to the asynchronous 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 asynchronously.</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 IAsyncEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, IEqualityComparer<TKey>? comparer)
         {
             if (source == null)
@@ -79,6 +141,16 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <summary>
+        /// Returns an observable sequence that contains only distinct contiguous elements according to the asynchronous and cancellable 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 asynchronously while supporting cancellation.</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 IAsyncEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector, IEqualityComparer<TKey> comparer)
         {
             if (source == null)

+ 129 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Do.cs

@@ -12,6 +12,15 @@ namespace System.Linq
     {
         // REVIEW: Should we convert Task-based overloads to ValueTask?
 
+        /// <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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Action<TSource> onNext)
         {
             if (source == null)
@@ -22,6 +31,16 @@ namespace System.Linq
             return DoCore(source, onNext: onNext, onError: null, onCompleted: null);
         }
 
+        /// <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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Action<TSource> onNext, Action onCompleted)
         {
             if (source == null)
@@ -34,6 +53,16 @@ namespace System.Linq
             return DoCore(source, onNext: onNext, onError: null, onCompleted: 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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Action<TSource> onNext, Action<Exception> onError)
         {
             if (source == null)
@@ -46,6 +75,17 @@ namespace System.Linq
             return DoCore(source, onNext: onNext, onError: onError, onCompleted: null);
         }
 
+        /// <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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted)
         {
             if (source == null)
@@ -60,6 +100,15 @@ namespace System.Linq
             return DoCore(source, onNext, onError, onCompleted);
         }
 
+        /// <summary>
+        /// Invokes and awaits an asynchronous 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 and await 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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, Task> onNext)
         {
             if (source == null)
@@ -70,6 +119,16 @@ namespace System.Linq
             return DoCore(source, onNext: onNext, onError: null, onCompleted: null);
         }
 
+        /// <summary>
+        /// Invokes and awaits an asynchronous action for each element in the observable sequence, then invokes and awaits an asynchronous 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 and await for each element in the observable sequence.</param>
+        /// <param name="onCompleted">Action to invoke and await 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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, Task> onNext, Func<Task> onCompleted)
         {
             if (source == null)
@@ -82,6 +141,16 @@ namespace System.Linq
             return DoCore(source, onNext: onNext, onError: null, onCompleted: onCompleted);
         }
 
+        /// <summary>
+        /// Invokes and awaits an asynchronous action for each element in the observable sequence, then invokes and awaits an asynchronous 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 and await for each element in the observable sequence.</param>
+        /// <param name="onError">Action to invoke and await 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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, Task> onNext, Func<Exception, Task> onError)
         {
             if (source == null)
@@ -94,6 +163,17 @@ namespace System.Linq
             return DoCore(source, onNext: onNext, onError: onError, onCompleted: null);
         }
 
+        /// <summary>
+        /// Invokes and awaits an asynchronous action for each element in the observable sequence, then invokes and awaits an asynchronous 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 and await for each element in the observable sequence.</param>
+        /// <param name="onError">Action to invoke and await upon exceptional termination of the observable sequence.</param>
+        /// <param name="onCompleted">Action to invoke and await 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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, Task> onNext, Func<Exception, Task> onError, Func<Task> onCompleted)
         {
             if (source == null)
@@ -109,6 +189,15 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <summary>
+        /// Invokes and awaits an asynchronous (cancellable) 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 and await for each element in the observable sequence while supporting cancellation.</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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, Task> onNext)
         {
             if (source == null)
@@ -119,6 +208,16 @@ namespace System.Linq
             return DoCore(source, onNext: onNext, onError: null, onCompleted: null);
         }
 
+        /// <summary>
+        /// Invokes and awaits an asynchronous (cancellable) action for each element in the observable sequence, then invokes and awaits an asynchronous (cancellable) 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 and await for each element in the observable sequence while supporting cancellation.</param>
+        /// <param name="onCompleted">Action to invoke and await upon graceful termination of the observable sequence while supporting cancellation.</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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, Task> onNext, Func<CancellationToken, Task> onCompleted)
         {
             if (source == null)
@@ -131,6 +230,16 @@ namespace System.Linq
             return DoCore(source, onNext: onNext, onError: null, onCompleted: onCompleted);
         }
 
+        /// <summary>
+        /// Invokes and awaits an asynchronous (cancellable) action for each element in the observable sequence, then invokes and awaits an asynchronous (cancellable) 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 and await for each element in the observable sequence while supporting cancellation.</param>
+        /// <param name="onError">Action to invoke and await upon exceptional termination of the observable sequence while supporting cancellation.</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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, Task> onNext, Func<Exception, CancellationToken, Task> onError)
         {
             if (source == null)
@@ -143,6 +252,17 @@ namespace System.Linq
             return DoCore(source, onNext: onNext, onError: onError, onCompleted: null);
         }
 
+        /// <summary>
+        /// Invokes and awaits an asynchronous (cancellable) action for each element in the observable sequence, then invokes and awaits an asynchronous (cancellable) 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 and await for each element in the observable sequence while supporting cancellation.</param>
+        /// <param name="onError">Action to invoke and await upon exceptional termination of the observable sequence while supporting cancellation.</param>
+        /// <param name="onCompleted">Action to invoke and await upon graceful termination of the observable sequence while supporting cancellation.</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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, Task> onNext, Func<Exception, CancellationToken, Task> onError, Func<CancellationToken, Task> onCompleted)
         {
             if (source == null)
@@ -158,6 +278,15 @@ namespace System.Linq
         }
 #endif
 
+        /// <summary>
+        /// Invokes the observer's methods for each message in the source async-enumerable 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 IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, IObserver<TSource> observer)
         {
             if (source == null)

+ 21 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Expand.cs

@@ -10,6 +10,13 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <summary>
+        /// Expands (breadth first) the async-enumerable sequence by recursively applying a selector function to generate more sequences at each recursion level.
+        /// </summary>
+        /// <typeparam name="TSource">Source sequence element type.</typeparam>
+        /// <param name="source">Source async-enumerable sequence.</param>
+        /// <param name="selector">Selector function to retrieve the next sequence to expand.</param>
+        /// <returns>Sequence with results from the recursive expansion of the source sequence.</returns>
         public static IAsyncEnumerable<TSource> Expand<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, IAsyncEnumerable<TSource>> selector)
         {
             if (source == null)
@@ -37,6 +44,13 @@ namespace System.Linq
             }
         }
 
+        /// <summary>
+        /// Expands (breadth first) the async-enumerable sequence by recursively applying an asynchronous selector function to generate more sequences at each recursion level.
+        /// </summary>
+        /// <typeparam name="TSource">Source sequence element type.</typeparam>
+        /// <param name="source">Source async-enumerable sequence.</param>
+        /// <param name="selector">Asynchronous selector function to retrieve the next sequence to expand.</param>
+        /// <returns>Sequence with results from the recursive expansion of the source sequence.</returns>
         public static IAsyncEnumerable<TSource> Expand<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<IAsyncEnumerable<TSource>>> selector)
         {
             if (source == null)
@@ -65,6 +79,13 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <summary>
+        /// Expands (breadth first) the async-enumerable sequence by recursively applying an asynchronous (cancellable) selector function to generate more sequences at each recursion level.
+        /// </summary>
+        /// <typeparam name="TSource">Source sequence element type.</typeparam>
+        /// <param name="source">Source async-enumerable sequence.</param>
+        /// <param name="selector">Asynchronous (cancellable) selector function to retrieve the next sequence to expand.</param>
+        /// <returns>Sequence with results from the recursive expansion of the source sequence.</returns>
         public static IAsyncEnumerable<TSource> Expand<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<IAsyncEnumerable<TSource>>> selector)
         {
             if (source == null)

+ 16 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Finally.cs

@@ -10,6 +10,14 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 IAsyncEnumerable<TSource> Finally<TSource>(this IAsyncEnumerable<TSource> source, Action finallyAction)
         {
             if (source == null)
@@ -35,6 +43,14 @@ namespace System.Linq
             }
         }
 
+        /// <summary>
+        /// Invokes a specified asynchronous 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 and await asynchronously 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 IAsyncEnumerable<TSource> Finally<TSource>(this IAsyncEnumerable<TSource> source, Func<Task> finallyAction)
         {
             if (source == null)

+ 11 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Generate.cs

@@ -11,6 +11,17 @@ namespace System.Linq
     {
         // REVIEW: Add async variant?
 
+        /// <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 IAsyncEnumerable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector)
         {
             if (condition == null)

+ 7 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/IgnoreElements.cs

@@ -10,6 +10,13 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 IAsyncEnumerable<TSource> IgnoreElements<TSource>(this IAsyncEnumerable<TSource> source)
         {
             if (source == null)

+ 8 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/IsEmpty.cs

@@ -10,6 +10,14 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</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 ValueTask<bool> IsEmptyAsync<TSource>(this IAsyncEnumerable<TSource> source, CancellationToken cancellationToken = default)
         {
             if (source == null)

+ 10 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Max.cs

@@ -10,6 +10,16 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</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 ValueTask<TSource> MaxAsync<TSource>(this IAsyncEnumerable<TSource> source, IComparer<TSource>? comparer, CancellationToken cancellationToken = default)
         {
             if (source == null)

+ 69 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxBy.cs

@@ -10,6 +10,17 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MaxByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, CancellationToken cancellationToken = default)
         {
             if (source == null)
@@ -20,6 +31,18 @@ namespace System.Linq
             return MaxByCore(source, keySelector, comparer: null, cancellationToken);
         }
 
+        /// <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>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MaxByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey>? comparer, CancellationToken cancellationToken = default)
         {
             if (source == null)
@@ -30,6 +53,17 @@ namespace System.Linq
             return MaxByCore(source, keySelector, comparer, cancellationToken);
         }
 
+        /// <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 returning a key possibly asynchronously.</param>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MaxByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, CancellationToken cancellationToken = default)
         {
             if (source == null)
@@ -41,6 +75,17 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <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 returning a key possibly asynchronously and supporting cancellation.</param>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MaxByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector, CancellationToken cancellationToken = default)
         {
             if (source == null)
@@ -52,6 +97,18 @@ namespace System.Linq
         }
 #endif
 
+        /// <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 returning a key possibly asynchronously.</param>
+        /// <param name="comparer">Comparer used to compare key values.</param>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MaxByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, IComparer<TKey>? comparer, CancellationToken cancellationToken = default)
         {
             if (source == null)
@@ -63,6 +120,18 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <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 returning a key possibly asynchronously and supporting cancellation.</param>
+        /// <param name="comparer">Comparer used to compare key values.</param>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MaxByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector, IComparer<TKey>? comparer, CancellationToken cancellationToken = default)
         {
             if (source == null)

+ 21 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Merge.cs

@@ -10,6 +10,13 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 IAsyncEnumerable<TSource> Merge<TSource>(params IAsyncEnumerable<TSource>[] sources)
         {
             if (sources == null)
@@ -296,6 +303,13 @@ namespace System.Linq
 #endif
         }
 
+        /// <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 IAsyncEnumerable<TSource> Merge<TSource>(this IEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
@@ -323,6 +337,13 @@ namespace System.Linq
             return sources.ToAsyncEnumerable().SelectMany(source => source);
         }
 
+        /// <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 IAsyncEnumerable<TSource> Merge<TSource>(this IAsyncEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)

+ 10 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Min.cs

@@ -10,6 +10,16 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 minimum element of.</param>
+        /// <param name="comparer">Comparer used to compare elements.</param>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</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 ValueTask<TSource> MinAsync<TSource>(this IAsyncEnumerable<TSource> source, IComparer<TSource>? comparer, CancellationToken cancellationToken = default)
         {
             if (source == null)

+ 69 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinBy.cs

@@ -10,6 +10,17 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MinByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, CancellationToken cancellationToken = default)
         {
             if (source == null)
@@ -20,6 +31,18 @@ namespace System.Linq
             return MinByCore(source, keySelector, comparer: null, cancellationToken);
         }
 
+        /// <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>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MinByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey>? comparer, CancellationToken cancellationToken = default)
         {
             if (source == null)
@@ -30,6 +53,17 @@ namespace System.Linq
             return MinByCore(source, keySelector, comparer, cancellationToken);
         }
 
+        /// <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 returning a key possibly asynchronously.</param>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MinByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, CancellationToken cancellationToken = default)
         {
             if (source == null)
@@ -41,6 +75,17 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <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 returning a key possibly asynchronously and supporting cancellation.</param>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MinByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector, CancellationToken cancellationToken = default)
         {
             if (source == null)
@@ -52,6 +97,18 @@ namespace System.Linq
         }
 #endif
 
+        /// <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 returning a key possibly asynchronously.</param>
+        /// <param name="comparer">Comparer used to compare key values.</param>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MinByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, IComparer<TKey>? comparer, CancellationToken cancellationToken = default)
         {
             if (source == null)
@@ -63,6 +120,18 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <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 returning a key possibly asynchronously and supporting cancellation.</param>
+        /// <param name="comparer">Comparer used to compare key values.</param>
+        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
+        /// <returns>A ValueTask 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 ValueTask<IList<TSource>> MinByAsync<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken = default)
         {
             if (source == null)

+ 5 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Never.cs

@@ -10,6 +10,11 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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="TValue">The type used for the <see cref="IAsyncEnumerable{T}"/> type parameter of the resulting sequence.</typeparam>
+        /// <returns>An observable sequence whose consumers will never resume after awaiting <see cref="IAsyncEnumerator{T}.MoveNextAsync"/>.</returns>
         public static IAsyncEnumerable<TValue> Never<TValue>() => NeverAsyncEnumerable<TValue>.Instance;
 
         private sealed class NeverAsyncEnumerable<TValue> : IAsyncEnumerable<TValue>

+ 22 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/OnErrorResumeNext.cs

@@ -9,6 +9,14 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 IAsyncEnumerable<TSource> OnErrorResumeNext<TSource>(this IAsyncEnumerable<TSource> first, IAsyncEnumerable<TSource> second)
         {
             if (first == null)
@@ -19,6 +27,13 @@ namespace System.Linq
             return OnErrorResumeNextCore(new[] { 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 IAsyncEnumerable<TSource> OnErrorResumeNext<TSource>(params IAsyncEnumerable<TSource>[] sources)
         {
             if (sources == null)
@@ -27,6 +42,13 @@ namespace System.Linq
             return OnErrorResumeNextCore(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 IAsyncEnumerable<TSource> OnErrorResumeNext<TSource>(this IEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)

+ 22 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Repeat.cs

@@ -10,6 +10,12 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <summary>
+        /// Repeats the element indefinitely.
+        /// </summary>
+        /// <typeparam name="TResult">The type of the elements in the source sequence.</typeparam>
+        /// <param name="element">Element to repeat.</param>
+        /// <returns>The observable sequence producing the element repeatedly and sequentially.</returns>
         public static IAsyncEnumerable<TResult> Repeat<TResult>(TResult element)
         {
             return AsyncEnumerable.Create(Core);
@@ -27,6 +33,13 @@ namespace System.Linq
 #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
         }
 
+        /// <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 IAsyncEnumerable<TSource> Repeat<TSource>(this IAsyncEnumerable<TSource> source)
         {
             if (source == null)
@@ -46,6 +59,15 @@ namespace System.Linq
             }
         }
 
+        /// <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 IAsyncEnumerable<TSource> Repeat<TSource>(this IAsyncEnumerable<TSource> source, int count)
         {
             if (source == null)

+ 16 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Retry.cs

@@ -8,6 +8,13 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 IAsyncEnumerable<TSource> Retry<TSource>(this IAsyncEnumerable<TSource> source)
         {
             if (source == null)
@@ -16,6 +23,15 @@ namespace System.Linq
             return new[] { source }.Repeat().Catch();
         }
 
+        /// <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 IAsyncEnumerable<TSource> Retry<TSource>(this IAsyncEnumerable<TSource> source, int retryCount)
         {
             if (source == null)

+ 6 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Return.cs

@@ -10,6 +10,12 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <summary>
+        /// Returns an observable sequence that contains a single element.
+        /// </summary>
+        /// <typeparam name="TValue">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 IAsyncEnumerable<TValue> Return<TValue>(TValue value) => new ReturnEnumerable<TValue>(value);
 
         // REVIEW: Add support for IAsyncPartition<T>.

+ 60 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Scan.cs

@@ -14,6 +14,15 @@ namespace System.Linq
         //     element, which returns the first element (or the seed if given an empty sequence). This is compatible with Rx
         //     but one could argue whether it was the right default.
 
+        /// <summary>
+        /// Applies an accumulator function over an observable sequence and returns each intermediate result.
+        /// For aggregation behavior with no intermediate results, see <see cref="AsyncEnumerable.AggregateAsync{TSource}"/>.
+        /// </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 IAsyncEnumerable<TSource> Scan<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, TSource, TSource> accumulator)
         {
             if (source == null)
@@ -43,6 +52,17 @@ namespace System.Linq
             }
         }
 
+        /// <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="AsyncEnumerable.AggregateAsync{TSource, Accumulate}"/>.
+        /// </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 IAsyncEnumerable<TAccumulate> Scan<TSource, TAccumulate>(this IAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
         {
             if (source == null)
@@ -65,6 +85,15 @@ namespace System.Linq
             }
         }
 
+        /// <summary>
+        /// Applies an asynchronous accumulator function over an observable sequence and returns each intermediate result.
+        /// For aggregation behavior with no intermediate results, see <see cref="AsyncEnumerable.AggregateAsync{TSource}"/>.
+        /// </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 asynchronous accumulator function to be invoked and awaited 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 IAsyncEnumerable<TSource> Scan<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, TSource, ValueTask<TSource>> accumulator)
         {
             if (source == null)
@@ -95,6 +124,15 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <summary>
+        /// Applies an asynchronous (cancellable) accumulator function over an observable sequence and returns each intermediate result.
+        /// For aggregation behavior with no intermediate results, see <see cref="AsyncEnumerable.AggregateAsync{TSource}"/>.
+        /// </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 asynchronous (cancellable) accumulator function to be invoked and awaited 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 IAsyncEnumerable<TSource> Scan<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, TSource, CancellationToken, ValueTask<TSource>> accumulator)
         {
             if (source == null)
@@ -125,6 +163,17 @@ namespace System.Linq
         }
 #endif
 
+        /// <summary>
+        /// Applies an asynchronous 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="AsyncEnumerable.AggregateAsync{TSource, Accumulate}"/>.
+        /// </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 asynchronous 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 IAsyncEnumerable<TAccumulate> Scan<TSource, TAccumulate>(this IAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, ValueTask<TAccumulate>> accumulator)
         {
             if (source == null)
@@ -148,6 +197,17 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <summary>
+        /// Applies an asynchronous (cancellable) 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="AsyncEnumerable.AggregateAsync{TSource, Accumulate}"/>.
+        /// </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 asynchronous (cancellable) 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 IAsyncEnumerable<TAccumulate> Scan<TSource, TAccumulate>(this IAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, CancellationToken, ValueTask<TAccumulate>> accumulator)
         {
             if (source == null)

+ 9 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/SelectMany.cs

@@ -8,6 +8,15 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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 IAsyncEnumerable<TOther> SelectMany<TSource, TOther>(this IAsyncEnumerable<TSource> source, IAsyncEnumerable<TOther> other)
         {
             if (source == null)

+ 8 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/StartWith.cs

@@ -11,6 +11,14 @@ namespace System.Linq
         // REVIEW: This is really an n-ary Prepend. Should we add n-ary overloads of Append and Prepend as well?
         //         If so, likely in Ix rather than System.Linq.Async.
 
+        /// <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 IAsyncEnumerable<TSource> StartWith<TSource>(this IAsyncEnumerable<TSource> source, params TSource[] values)
         {
             if (source == null)

+ 7 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Throw.cs

@@ -10,6 +10,13 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <summary>
+        /// Returns an observable sequence that terminates with an exception.
+        /// </summary>
+        /// <typeparam name="TValue">The type used for the <see cref="IAsyncEnumerable{T}"/> 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 IAsyncEnumerable<TValue> Throw<TValue>(Exception exception)
         {
             if (exception == null)

+ 27 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Timeout.cs

@@ -10,6 +10,33 @@ namespace System.Linq
 {
     public static partial class AsyncEnumerableEx
     {
+        /// <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="timeout">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="timeout"/> is less than TimeSpan.Zero.</exception>
+        /// <exception cref="TimeoutException">(Asynchronous) If no element is produced within <paramref name="timeout"/> from the previous element.</exception>
+        /// <remarks>
+        /// <para>
+        /// In case you only want to timeout on the first element, consider using the <see cref="Amb{TSource}(IAsyncEnumerable{TSource}, IAsyncEnumerable{TSource})"/>
+        /// operator applied to the source sequence and a delayed <see cref="Throw{TResult}(Exception)"/> sequence.
+        /// <!-- FIXME: Timeout with initial and per item timeout option not implemented yet.
+        /// 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="timeout"/> 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 IAsyncEnumerable<TSource> Timeout<TSource>(this IAsyncEnumerable<TSource> source, TimeSpan timeout)
         {
             if (source == null)

+ 32 - 0
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Using.cs

@@ -12,6 +12,15 @@ namespace System.Linq
     {
         // REVIEW: Add support for IAsyncDisposable resources.
 
+        /// <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="TSource">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="IDisposable"/>.</typeparam>
+        /// <param name="resourceFactory">Factory function to obtain a resource object.</param>
+        /// <param name="enumerableFactory">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="enumerableFactory"/> is null.</exception>
         public static IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IAsyncEnumerable<TSource>> enumerableFactory) where TResource : IDisposable
         {
             if (resourceFactory == null)
@@ -32,6 +41,17 @@ namespace System.Linq
             }
         }
 
+        /// <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="TSource">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="IDisposable"/>.</typeparam>
+        /// <param name="resourceFactory">Asynchronous factory function to obtain a resource object.</param>
+        /// <param name="enumerableFactory">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="resourceFactory"/> or <paramref name="enumerableFactory"/> 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 IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<Task<TResource>> resourceFactory, Func<TResource, ValueTask<IAsyncEnumerable<TSource>>> enumerableFactory) where TResource : IDisposable
         {
             if (resourceFactory == null)
@@ -53,6 +73,18 @@ namespace System.Linq
         }
 
 #if !NO_DEEP_CANCELLATION
+        /// <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="TSource">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="IDisposable"/>.</typeparam>
+        /// <param name="resourceFactory">Asynchronous factory function to obtain a resource object.</param>
+        /// <param name="enumerableFactory">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="resourceFactory"/> or <paramref name="enumerableFactory"/> 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 IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<CancellationToken, Task<TResource>> resourceFactory, Func<TResource, CancellationToken, ValueTask<IAsyncEnumerable<TSource>>> enumerableFactory) where TResource : IDisposable
         {
             if (resourceFactory == null)