瀏覽代碼

Merge branch 'IxAsyncCSharp8' into AsyncIxCS8FixesPart2

Bart J.F. De Smet 7 年之前
父節點
當前提交
e3640ffff8
共有 100 個文件被更改,包括 2193 次插入2318 次删除
  1. 93 0
      Ix.NET/Source/Ix.Async.NET.sln
  2. 0 1
      Ix.NET/Source/System.Interactive.Async.Providers.Tests/System.Interactive.Async.Providers.Tests.csproj
  3. 4 0
      Ix.NET/Source/System.Interactive.Async.Providers/System.Interactive.Async.Providers.csproj
  4. 84 84
      Ix.NET/Source/System.Interactive.Async.Providers/System/Linq/AsyncQueryableEx.Generated.cs
  5. 1 1
      Ix.NET/Source/System.Interactive.Async.Providers/System/Linq/AsyncQueryableEx.Generated.tt
  6. 21 7
      Ix.NET/Source/System.Interactive.Async.Tests/AsyncTests.Bugs.cs
  7. 0 2
      Ix.NET/Source/System.Interactive.Async.Tests/System.Interactive.Async.Tests.csproj
  8. 19 34
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/AsyncEnumerableExTests.cs
  9. 19 19
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Buffer.cs
  10. 89 88
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Catch.cs
  11. 30 29
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Concat.cs
  12. 7 6
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Defer.cs
  13. 12 13
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Distinct.cs
  14. 29 31
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/DistinctUntilChanged.cs
  15. 38 38
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Do.cs
  16. 17 17
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Expand.cs
  17. 14 14
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Finally.cs
  18. 17 17
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Generate.cs
  19. 9 15
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/IgnoreElements.cs
  20. 0 2
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Max.cs
  21. 10 12
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/MaxBy.cs
  22. 0 2
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Min.cs
  23. 10 12
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/MinBy.cs
  24. 0 6
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Never.cs
  25. 53 52
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/OnErrorResumeNext.cs
  26. 43 43
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Repeat.cs
  27. 19 18
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Retry.cs
  28. 3 2
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Return.cs
  29. 17 17
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Scan.cs
  30. 11 11
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/SelectMany.cs
  31. 16 16
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/StartWith.cs
  32. 37 16
      Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Using.cs
  33. 0 110
      Ix.NET/Source/System.Interactive.Async/AsyncIterator.cs
  34. 7 0
      Ix.NET/Source/System.Interactive.Async/System.Interactive.Async.csproj
  35. 17 17
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Amb.cs
  36. 11 24
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Buffer.cs
  37. 27 27
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Catch.cs
  38. 14 14
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Concat.cs
  39. 96 3
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Defer.cs
  40. 25 29
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Distinct.cs
  41. 32 37
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/DistinctUntilChanged.cs
  42. 38 38
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Do.cs
  43. 14 14
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Expand.cs
  44. 14 14
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Finally.cs
  45. 7 15
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Generate.cs
  46. 5 7
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/IgnoreElements.cs
  47. 2 2
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/IsEmpty.cs
  48. 11 10
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Max.cs
  49. 30 28
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxBy.cs
  50. 8 8
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Merge.cs
  51. 10 9
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Min.cs
  52. 36 34
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinBy.cs
  53. 9 9
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/OnErrorResumeNext.cs
  54. 12 12
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Repeat.cs
  55. 3 3
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Retry.cs
  56. 28 28
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Scan.cs
  57. 2 2
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/SelectMany.cs
  58. 1 3
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/StartWith.cs
  59. 1 1
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Throw.cs
  60. 7 7
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Timeout.cs
  61. 19 25
      Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Using.cs
  62. 0 86
      Ix.NET/Source/System.Interactive.Async/System/Linq/Set.cs
  63. 0 13
      Ix.NET/Source/System.Interactive.Async/System/Linq/Strings.cs
  64. 0 3
      Ix.NET/Source/System.Interactive.Async/TaskExt.cs
  65. 4 0
      Ix.NET/Source/System.Linq.Async.Queryable/System.Linq.Async.Queryable.csproj
  66. 5 35
      Ix.NET/Source/System.Linq.Async.Queryable/System/Linq/AsyncEnumerableQuery.cs
  67. 0 1
      Ix.NET/Source/System.Linq.Async.Queryable/System/Linq/AsyncEnumerableRewriter.cs
  68. 172 172
      Ix.NET/Source/System.Linq.Async.Queryable/System/Linq/AsyncQueryable.Generated.cs
  69. 1 1
      Ix.NET/Source/System.Linq.Async.Queryable/System/Linq/AsyncQueryable.Generated.tt
  70. 40 34
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/AsyncEnumerableTests.cs
  71. 32 33
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Aggregate.cs
  72. 10 11
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/All.cs
  73. 14 15
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Any.cs
  74. 15 15
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Append.cs
  75. 1 13
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/AsAsyncEnumerable.cs
  76. 50 50
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Average.cs
  77. 8 8
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Cast.cs
  78. 30 30
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Concat.cs
  79. 12 14
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Contains.cs
  80. 24 13
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Count.cs
  81. 1 4
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/CreateEnumerable.cs
  82. 3 3
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/CreateEnumerator.cs
  83. 30 30
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/DefaultIfEmpty.cs
  84. 18 19
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Distinct.cs
  85. 14 15
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/ElementAt.cs
  86. 19 16
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/ElementAtOrDefault.cs
  87. 3 12
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Empty.cs
  88. 10 11
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Except.cs
  89. 20 21
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/First.cs
  90. 22 23
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/FirstOrDefault.cs
  91. 18 17
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/ForEachAsync.cs
  92. 177 220
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.cs
  93. 33 33
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupJoin.cs
  94. 12 13
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Intersect.cs
  95. 55 56
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Join.cs
  96. 20 21
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Last.cs
  97. 22 23
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/LastOrDefault.cs
  98. 24 13
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/LongCount.cs
  99. 33 33
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Max.cs
  100. 33 33
      Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Min.cs

+ 93 - 0
Ix.NET/Source/Ix.Async.NET.sln

@@ -0,0 +1,93 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.3
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{87534290-A7A6-47A4-9A3A-D0D21A9AD1D4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B733D97A-F1ED-4FC3-BF8E-9AC47A89DE96}"
+	ProjectSection(SolutionItems) = preProject
+		..\..\.editorconfig = ..\..\.editorconfig
+		..\..\azure-pipelines.ix.yml = ..\..\azure-pipelines.ix.yml
+		CodeCoverage.runsettings = CodeCoverage.runsettings
+		Directory.build.props = Directory.build.props
+		Directory.build.targets = Directory.build.targets
+		global.json = global.json
+		NuGet.Config = NuGet.Config
+		version.json = version.json
+	EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Interactive.Async", "System.Interactive.Async\System.Interactive.Async.csproj", "{A9F6D09B-15B9-4CE8-867F-6F3383C5F247}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Interactive.Async.Providers", "System.Interactive.Async.Providers\System.Interactive.Async.Providers.csproj", "{33691BB5-DD5B-4FED-8EE3-52CEE0DE2550}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Interactive.Async.Tests", "System.Interactive.Async.Tests\System.Interactive.Async.Tests.csproj", "{172BD8C4-5C3E-4928-9D3F-746CF336FFEC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Linq.Async", "System.Linq.Async\System.Linq.Async.csproj", "{9B1E5420-E8F3-4B5F-A11A-4D18578F50CE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Linq.Async.Queryable", "System.Linq.Async.Queryable\System.Linq.Async.Queryable.csproj", "{513F9ABD-4FB8-4AC1-89DA-C3300399F34C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{80EFE3A1-1414-42EA-949B-1B5370A1B2EA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Linq.Async.Tests", "System.Linq.Async.Tests\System.Linq.Async.Tests.csproj", "{2E23D7AD-0B21-4725-87C4-BD43271260A1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Linq.Async.Queryable.Tests", "System.Linq.Async.Queryable.Tests\System.Linq.Async.Queryable.Tests.csproj", "{134E9066-6217-4AF0-B408-47D92AB595BD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Interactive.Async.Providers.Tests", "System.Interactive.Async.Providers.Tests\System.Interactive.Async.Providers.Tests.csproj", "{974056C0-91BD-4EB6-8431-E30A614FD1D4}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{A9F6D09B-15B9-4CE8-867F-6F3383C5F247}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A9F6D09B-15B9-4CE8-867F-6F3383C5F247}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A9F6D09B-15B9-4CE8-867F-6F3383C5F247}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A9F6D09B-15B9-4CE8-867F-6F3383C5F247}.Release|Any CPU.Build.0 = Release|Any CPU
+		{33691BB5-DD5B-4FED-8EE3-52CEE0DE2550}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{33691BB5-DD5B-4FED-8EE3-52CEE0DE2550}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{33691BB5-DD5B-4FED-8EE3-52CEE0DE2550}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{33691BB5-DD5B-4FED-8EE3-52CEE0DE2550}.Release|Any CPU.Build.0 = Release|Any CPU
+		{172BD8C4-5C3E-4928-9D3F-746CF336FFEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{172BD8C4-5C3E-4928-9D3F-746CF336FFEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{172BD8C4-5C3E-4928-9D3F-746CF336FFEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{172BD8C4-5C3E-4928-9D3F-746CF336FFEC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9B1E5420-E8F3-4B5F-A11A-4D18578F50CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9B1E5420-E8F3-4B5F-A11A-4D18578F50CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9B1E5420-E8F3-4B5F-A11A-4D18578F50CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9B1E5420-E8F3-4B5F-A11A-4D18578F50CE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{513F9ABD-4FB8-4AC1-89DA-C3300399F34C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{513F9ABD-4FB8-4AC1-89DA-C3300399F34C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{513F9ABD-4FB8-4AC1-89DA-C3300399F34C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{513F9ABD-4FB8-4AC1-89DA-C3300399F34C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2E23D7AD-0B21-4725-87C4-BD43271260A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2E23D7AD-0B21-4725-87C4-BD43271260A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2E23D7AD-0B21-4725-87C4-BD43271260A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2E23D7AD-0B21-4725-87C4-BD43271260A1}.Release|Any CPU.Build.0 = Release|Any CPU
+		{134E9066-6217-4AF0-B408-47D92AB595BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{134E9066-6217-4AF0-B408-47D92AB595BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{134E9066-6217-4AF0-B408-47D92AB595BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{134E9066-6217-4AF0-B408-47D92AB595BD}.Release|Any CPU.Build.0 = Release|Any CPU
+		{974056C0-91BD-4EB6-8431-E30A614FD1D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{974056C0-91BD-4EB6-8431-E30A614FD1D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{974056C0-91BD-4EB6-8431-E30A614FD1D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{974056C0-91BD-4EB6-8431-E30A614FD1D4}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{A9F6D09B-15B9-4CE8-867F-6F3383C5F247} = {80EFE3A1-1414-42EA-949B-1B5370A1B2EA}
+		{33691BB5-DD5B-4FED-8EE3-52CEE0DE2550} = {80EFE3A1-1414-42EA-949B-1B5370A1B2EA}
+		{172BD8C4-5C3E-4928-9D3F-746CF336FFEC} = {87534290-A7A6-47A4-9A3A-D0D21A9AD1D4}
+		{9B1E5420-E8F3-4B5F-A11A-4D18578F50CE} = {80EFE3A1-1414-42EA-949B-1B5370A1B2EA}
+		{513F9ABD-4FB8-4AC1-89DA-C3300399F34C} = {80EFE3A1-1414-42EA-949B-1B5370A1B2EA}
+		{2E23D7AD-0B21-4725-87C4-BD43271260A1} = {87534290-A7A6-47A4-9A3A-D0D21A9AD1D4}
+		{134E9066-6217-4AF0-B408-47D92AB595BD} = {87534290-A7A6-47A4-9A3A-D0D21A9AD1D4}
+		{974056C0-91BD-4EB6-8431-E30A614FD1D4} = {87534290-A7A6-47A4-9A3A-D0D21A9AD1D4}
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {AF70B0C6-C9D9-43B1-9BE4-08720EC1B7B7}
+	EndGlobalSection
+EndGlobal

+ 0 - 1
Ix.NET/Source/System.Interactive.Async.Providers.Tests/System.Interactive.Async.Providers.Tests.csproj

@@ -14,7 +14,6 @@
 
   <ItemGroup>
     <ProjectReference Include="..\System.Interactive.Async.Providers\System.Interactive.Async.Providers.csproj" />
-    <ProjectReference Include="..\System.Interactive\System.Interactive.csproj" />
     <ProjectReference Include="..\System.Linq.Async\System.Linq.Async.csproj" />
   </ItemGroup>
 

+ 4 - 0
Ix.NET/Source/System.Interactive.Async.Providers/System.Interactive.Async.Providers.csproj

@@ -25,4 +25,8 @@
     <Compile Update="System\Linq\AsyncQueryableEx.Generated.cs" DesignTime="True" AutoGen="True" DependentUpon="AsyncQueryableEx.Generated.tt" />
   </ItemGroup>
 
+  <ItemGroup>
+    <Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
+  </ItemGroup>
+
 </Project>

+ 84 - 84
Ix.NET/Source/System.Interactive.Async.Providers/System/Linq/AsyncQueryableEx.Generated.cs

@@ -104,7 +104,7 @@ namespace System.Linq
 #endif
         }
 
-        public static IAsyncQueryable<TSource> Distinct<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
+        public static IAsyncQueryable<TSource> Distinct<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -112,13 +112,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(keySelector));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Distinct<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>))), source.Expression, keySelector));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Distinct<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>))), source.Expression, keySelector));
 #else
             return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector));
 #endif
         }
 
-        public static IAsyncQueryable<TSource> Distinct<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector)
+        public static IAsyncQueryable<TSource> Distinct<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -126,13 +126,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(keySelector));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Distinct<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>))), source.Expression, keySelector));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Distinct<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>))), source.Expression, keySelector));
 #else
             return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector));
 #endif
         }
 
-        public static IAsyncQueryable<TSource> Distinct<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IEqualityComparer<TKey> comparer)
+        public static IAsyncQueryable<TSource> Distinct<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IEqualityComparer<TKey> comparer)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -142,13 +142,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Distinct<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IEqualityComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Distinct<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IEqualityComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
 #else
             return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
 #endif
         }
 
-        public static IAsyncQueryable<TSource> Distinct<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IEqualityComparer<TKey> comparer)
+        public static IAsyncQueryable<TSource> Distinct<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IEqualityComparer<TKey> comparer)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -158,7 +158,7 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Distinct<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IEqualityComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Distinct<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IEqualityComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
 #else
             return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
 #endif
@@ -190,7 +190,7 @@ namespace System.Linq
 #endif
         }
 
-        public static IAsyncQueryable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
+        public static IAsyncQueryable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -198,13 +198,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(keySelector));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.DistinctUntilChanged<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>))), source.Expression, keySelector));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.DistinctUntilChanged<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>))), source.Expression, keySelector));
 #else
             return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector));
 #endif
         }
 
-        public static IAsyncQueryable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector)
+        public static IAsyncQueryable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -212,13 +212,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(keySelector));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.DistinctUntilChanged<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>))), source.Expression, keySelector));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.DistinctUntilChanged<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>))), source.Expression, keySelector));
 #else
             return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector));
 #endif
         }
 
-        public static IAsyncQueryable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IEqualityComparer<TKey> comparer)
+        public static IAsyncQueryable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IEqualityComparer<TKey> comparer)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -228,13 +228,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.DistinctUntilChanged<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IEqualityComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.DistinctUntilChanged<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IEqualityComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
 #else
             return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
 #endif
         }
 
-        public static IAsyncQueryable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IEqualityComparer<TKey> comparer)
+        public static IAsyncQueryable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IEqualityComparer<TKey> comparer)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -244,26 +244,12 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.DistinctUntilChanged<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IEqualityComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.DistinctUntilChanged<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IEqualityComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
 #else
             return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))));
 #endif
         }
 
-        public static IAsyncQueryable<TSource> Do<TSource>(this IAsyncQueryable<TSource> source, IObserver<TSource> observer)
-        {
-            if (source == null)
-                throw new ArgumentNullException(nameof(source));
-            if (observer == null)
-                throw new ArgumentNullException(nameof(observer));
-
-#if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Do<TSource>(default(IAsyncQueryable<TSource>), default(IObserver<TSource>))), source.Expression, Expression.Constant(observer, typeof(IObserver<TSource>))));
-#else
-            return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), source.Expression, Expression.Constant(observer, typeof(IObserver<TSource>))));
-#endif
-        }
-
         public static IAsyncQueryable<TSource> Do<TSource>(this IAsyncQueryable<TSource> source, Expression<Action<TSource>> onNext)
         {
             if (source == null)
@@ -292,23 +278,21 @@ namespace System.Linq
 #endif
         }
 
-        public static IAsyncQueryable<TSource> Do<TSource>(this IAsyncQueryable<TSource> source, Expression<Action<TSource>> onNext, Action onCompleted)
+        public static IAsyncQueryable<TSource> Do<TSource>(this IAsyncQueryable<TSource> source, IObserver<TSource> observer)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
-            if (onNext == null)
-                throw new ArgumentNullException(nameof(onNext));
-            if (onCompleted == null)
-                throw new ArgumentNullException(nameof(onCompleted));
+            if (observer == null)
+                throw new ArgumentNullException(nameof(observer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Do<TSource>(default(IAsyncQueryable<TSource>), default(Expression<Action<TSource>>), default(Action))), source.Expression, onNext, Expression.Constant(onCompleted, typeof(Action))));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Do<TSource>(default(IAsyncQueryable<TSource>), default(IObserver<TSource>))), source.Expression, Expression.Constant(observer, typeof(IObserver<TSource>))));
 #else
-            return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), source.Expression, onNext, Expression.Constant(onCompleted, typeof(Action))));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), source.Expression, Expression.Constant(observer, typeof(IObserver<TSource>))));
 #endif
         }
 
-        public static IAsyncQueryable<TSource> Do<TSource>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task>> onNext, Expression<Func<Task>> onCompleted)
+        public static IAsyncQueryable<TSource> Do<TSource>(this IAsyncQueryable<TSource> source, Expression<Action<TSource>> onNext, Action onCompleted)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -318,9 +302,9 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(onCompleted));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Do<TSource>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task>>), default(Expression<Func<Task>>))), source.Expression, onNext, onCompleted));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Do<TSource>(default(IAsyncQueryable<TSource>), default(Expression<Action<TSource>>), default(Action))), source.Expression, onNext, Expression.Constant(onCompleted, typeof(Action))));
 #else
-            return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), source.Expression, onNext, onCompleted));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), source.Expression, onNext, Expression.Constant(onCompleted, typeof(Action))));
 #endif
         }
 
@@ -356,6 +340,22 @@ namespace System.Linq
 #endif
         }
 
+        public static IAsyncQueryable<TSource> Do<TSource>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task>> onNext, Expression<Func<Task>> onCompleted)
+        {
+            if (source == null)
+                throw new ArgumentNullException(nameof(source));
+            if (onNext == null)
+                throw new ArgumentNullException(nameof(onNext));
+            if (onCompleted == null)
+                throw new ArgumentNullException(nameof(onCompleted));
+
+#if CRIPPLED_REFLECTION
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Do<TSource>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task>>), default(Expression<Func<Task>>))), source.Expression, onNext, onCompleted));
+#else
+            return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), source.Expression, onNext, onCompleted));
+#endif
+        }
+
         public static IAsyncQueryable<TSource> Do<TSource>(this IAsyncQueryable<TSource> source, Expression<Action<TSource>> onNext, Expression<Action<Exception>> onError, Action onCompleted)
         {
             if (source == null)
@@ -512,7 +512,7 @@ namespace System.Linq
 #endif
         }
 
-        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
+        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -520,13 +520,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(keySelector));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>))), source.Expression, keySelector), CancellationToken.None);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>))), source.Expression, keySelector), CancellationToken.None);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector), CancellationToken.None);
 #endif
         }
 
-        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector)
+        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -534,13 +534,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(keySelector));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>))), source.Expression, keySelector), CancellationToken.None);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>))), source.Expression, keySelector), CancellationToken.None);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector), CancellationToken.None);
 #endif
         }
 
-        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, CancellationToken cancellationToken)
+        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, CancellationToken cancellationToken)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -548,43 +548,43 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(keySelector));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #endif
         }
 
-        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, CancellationToken cancellationToken)
+        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IComparer<TKey> comparer)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
             if (keySelector == null)
                 throw new ArgumentNullException(nameof(keySelector));
+            if (comparer == null)
+                throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
 #else
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
 #endif
         }
 
-        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
+        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, CancellationToken cancellationToken)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
             if (keySelector == null)
                 throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #else
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #endif
         }
 
-        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IComparer<TKey> comparer)
+        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -594,13 +594,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
 #endif
         }
 
-        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
+        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -610,13 +610,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IComparer<TKey>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IComparer<TKey>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #endif
         }
 
-        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
+        public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -626,7 +626,7 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IComparer<TKey>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MaxBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IComparer<TKey>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #endif
@@ -672,7 +672,7 @@ namespace System.Linq
 #endif
         }
 
-        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
+        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -680,13 +680,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(keySelector));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>))), source.Expression, keySelector), CancellationToken.None);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>))), source.Expression, keySelector), CancellationToken.None);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector), CancellationToken.None);
 #endif
         }
 
-        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector)
+        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -694,13 +694,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(keySelector));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>))), source.Expression, keySelector), CancellationToken.None);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>))), source.Expression, keySelector), CancellationToken.None);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector), CancellationToken.None);
 #endif
         }
 
-        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, CancellationToken cancellationToken)
+        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, CancellationToken cancellationToken)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -708,43 +708,43 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(keySelector));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #endif
         }
 
-        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, CancellationToken cancellationToken)
+        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IComparer<TKey> comparer)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
             if (keySelector == null)
                 throw new ArgumentNullException(nameof(keySelector));
+            if (comparer == null)
+                throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
 #else
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
 #endif
         }
 
-        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
+        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, CancellationToken cancellationToken)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
             if (keySelector == null)
                 throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #else
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #endif
         }
 
-        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IComparer<TKey> comparer)
+        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -754,13 +754,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IComparer<TKey>))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>))), CancellationToken.None);
 #endif
         }
 
-        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
+        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -770,13 +770,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IComparer<TKey>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IComparer<TKey>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #endif
         }
 
-        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, Task<TKey>>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
+        public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -786,7 +786,7 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(comparer));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, Task<TKey>>>), default(IComparer<TKey>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
+            return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(InfoOf(() => AsyncQueryableEx.MinBy<TSource, TKey>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IComparer<TKey>), default(CancellationToken))), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #else
             return source.Provider.ExecuteAsync<IList<TSource>>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer<TKey>)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken);
 #endif
@@ -854,7 +854,7 @@ namespace System.Linq
 #endif
         }
 
-        public static IAsyncQueryable<TSource> Scan<TSource>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TSource, TSource>> accumulator)
+        public static IAsyncQueryable<TSource> Scan<TSource>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TSource, Task<TSource>>> accumulator)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -862,13 +862,13 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(accumulator));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Scan<TSource>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TSource, TSource>>))), source.Expression, accumulator));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Scan<TSource>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TSource, Task<TSource>>>))), source.Expression, accumulator));
 #else
             return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), source.Expression, accumulator));
 #endif
         }
 
-        public static IAsyncQueryable<TSource> Scan<TSource>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TSource, Task<TSource>>> accumulator)
+        public static IAsyncQueryable<TSource> Scan<TSource>(this IAsyncQueryable<TSource> source, Expression<Func<TSource, TSource, TSource>> accumulator)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -876,7 +876,7 @@ namespace System.Linq
                 throw new ArgumentNullException(nameof(accumulator));
 
 #if CRIPPLED_REFLECTION
-            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Scan<TSource>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TSource, Task<TSource>>>))), source.Expression, accumulator));
+            return source.Provider.CreateQuery<TSource>(Expression.Call(InfoOf(() => AsyncQueryableEx.Scan<TSource>(default(IAsyncQueryable<TSource>), default(Expression<Func<TSource, TSource, TSource>>))), source.Expression, accumulator));
 #else
             return source.Provider.CreateQuery<TSource>(Expression.Call(((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), source.Expression, accumulator));
 #endif

+ 1 - 1
Ix.NET/Source/System.Interactive.Async.Providers/System/Linq/AsyncQueryableEx.Generated.tt

@@ -130,7 +130,7 @@ foreach (var m in typeof(AsyncEnumerableEx).GetMethods()
                         .OrderBy(m => m.Name)
                         .ThenBy(m => m.IsGenericMethod ? m.GetGenericArguments().Length : 0)
                         .ThenBy(m => m.GetParameters().Length)
-                        .ThenBy(m => string.Join(", ", m.GetParameters().Select(p => p.Name))))
+                        .ThenBy(m => string.Join(", ", m.GetParameters().Select((p, i) => toQuoted(p.ParameterType, i) + " " + p.Name))))
 {
     var genArgs = m.GetGenericArguments();
 

+ 21 - 7
Ix.NET/Source/System.Interactive.Async.Tests/AsyncTests.Bugs.cs

@@ -41,9 +41,9 @@ namespace Tests
 
             await disposed.Task;
 
-            Assert.True(disposed.Task.Result);
+            Assert.True(await disposed.Task);
 
-            Assert.False(e.MoveNextAsync().Result);
+            Assert.False(await e.MoveNextAsync());
 
             var next = await e.MoveNextAsync();
             Assert.False(next);
@@ -92,22 +92,22 @@ namespace Tests
         }
 
         [Fact]
-        public void SelectManyDisposeInvokedOnlyOnce()
+        public async Task SelectManyDisposeInvokedOnlyOnceAsync()
         {
             var disposeCounter = new DisposeCounter();
 
-            var result = new[] { 1 }.ToAsyncEnumerable().SelectMany(i => disposeCounter).Select(i => i).ToList().Result;
+            var result = await new[] { 1 }.ToAsyncEnumerable().SelectMany(i => disposeCounter).Select(i => i).ToList();
 
             Assert.Empty(result);
             Assert.Equal(1, disposeCounter.DisposeCount);
         }
 
         [Fact]
-        public void SelectManyInnerDispose()
+        public async Task SelectManyInnerDisposeAsync()
         {
             var disposes = Enumerable.Range(0, 10).Select(_ => new DisposeCounter()).ToList();
 
-            var result = AsyncEnumerable.Range(0, 10).SelectMany(i => disposes[i]).Select(i => i).ToList().Result;
+            var result = await AsyncEnumerable.Range(0, 10).SelectMany(i => disposes[i]).Select(i => i).ToList();
 
             Assert.Empty(result);
             Assert.True(disposes.All(d => d.DisposeCount == 1));
@@ -158,13 +158,27 @@ namespace Tests
     {
         public static IEnumerable<T> WithDispose<T>(this IEnumerable<T> source, Action a)
         {
-            return EnumerableEx.Create(() =>
+            return new Enumerable<T>(() =>
             {
                 var e = source.GetEnumerator();
                 return new Enumerator<T>(e.MoveNext, () => e.Current, () => { e.Dispose(); a(); });
             });
         }
 
+        private sealed class Enumerable<T> : IEnumerable<T>
+        {
+            private readonly Func<IEnumerator<T>> _getEnumerator;
+
+            public Enumerable(Func<IEnumerator<T>> getEnumerator)
+            {
+                _getEnumerator = getEnumerator;
+            }
+
+            public IEnumerator<T> GetEnumerator() => _getEnumerator();
+
+            IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+        }
+
         private sealed class Enumerator<T> : IEnumerator<T>
         {
             private readonly Func<bool> _moveNext;

+ 0 - 2
Ix.NET/Source/System.Interactive.Async.Tests/System.Interactive.Async.Tests.csproj

@@ -14,7 +14,6 @@
 
   <ItemGroup>
     <ProjectReference Include="..\System.Interactive.Async.Providers\System.Interactive.Async.Providers.csproj" />
-    <ProjectReference Include="..\System.Interactive\System.Interactive.csproj" />
     <ProjectReference Include="..\System.Linq.Async\System.Linq.Async.csproj" />
   </ItemGroup>
 
@@ -29,7 +28,6 @@
 
   <ItemGroup>
     <Compile Include="..\System.Linq.Async.Tests\ValueTaskHelpers.cs" />
-    <Compile Include="..\System.Linq.Async.Tests\TaskExt.cs" />
   </ItemGroup>
 
   <ItemGroup>

+ 19 - 34
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/AsyncEnumerableExTests.cs

@@ -15,50 +15,42 @@ namespace Tests
     {
         protected static readonly IAsyncEnumerable<int> Return42 = AsyncEnumerableEx.Return(42);
         protected static IAsyncEnumerable<T> Throw<T>(Exception exception) => AsyncEnumerableEx.Throw<T>(exception);
-        protected static Func<Exception, bool> SingleInnerExceptionMatches(Exception ex) => e => ((AggregateException)e).Flatten().InnerExceptions.Single() == ex;
 
-        protected const int WaitTimeoutMs = 5000;
-
-#pragma warning disable xUnit1013 // Public method should be marked as test
-        public void AssertThrows<E>(Action a)
-            where E : Exception
+        protected async Task AssertThrowsAsync<TException>(Task t)
+            where TException : Exception
         {
-            Assert.Throws<E>(a);
+            await Assert.ThrowsAsync<TException>(() => t);
         }
 
-        public void AssertThrows<E>(Action a, Func<E, bool> assert)
-            where E : Exception
+        protected async Task AssertThrowsAsync(Task t, Exception e)
         {
-            var hasFailed = false;
-
             try
             {
-                a();
+                await t;
             }
-            catch (E e)
+            catch (Exception ex)
             {
-                Assert.True(assert(e));
-                hasFailed = true;
+                Assert.Same(e, ex);
             }
+        }
 
-            if (!hasFailed)
-            {
-                Assert.True(false);
-            }
+        protected Task AssertThrowsAsync<T>(ValueTask<T> t, Exception e)
+        {
+            return AssertThrowsAsync(t.AsTask(), e);
         }
 
-        public void NoNext<T>(IAsyncEnumerator<T> e)
+        protected async Task NoNextAsync<T>(IAsyncEnumerator<T> e)
         {
-            Assert.False(e.MoveNextAsync().Result);
+            Assert.False(await e.MoveNextAsync());
         }
 
-        public void HasNext<T>(IAsyncEnumerator<T> e, T value)
+        protected async Task HasNextAsync<T>(IAsyncEnumerator<T> e, T value)
         {
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.Equal(value, e.Current);
         }
 
-        public async Task SequenceIdentity<T>(IAsyncEnumerable<T> enumerable)
+        protected async Task SequenceIdentity<T>(IAsyncEnumerable<T> enumerable)
         {
             var en1 = enumerable.GetAsyncEnumerator();
             var en2 = enumerable.GetAsyncEnumerator();
@@ -68,17 +60,10 @@ namespace Tests
             await en1.DisposeAsync();
             await en2.DisposeAsync();
 
-            var e1t = enumerable.ToList();
-            var e2t = enumerable.ToList();
-
-            await Task.WhenAll(e1t, e2t);
-
-
-            var e1Result = e1t.Result;
-            var e2Result = e2t.Result;
+            var res1 = await enumerable.ToList();
+            var res2 = await enumerable.ToList();
 
-            e1Result.ShouldAllBeEquivalentTo(e2Result);
+            res1.ShouldAllBeEquivalentTo(res2);
         }
-#pragma warning restore xUnit1013 // Public method should be marked as test
     }
 }

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

@@ -15,66 +15,66 @@ namespace Tests
         [Fact]
         public void Buffer_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Buffer(default(IAsyncEnumerable<int>), 1));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Buffer(default(IAsyncEnumerable<int>), 1, 1));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Buffer(default(IAsyncEnumerable<int>), 1));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Buffer(default(IAsyncEnumerable<int>), 1, 1));
 
-            AssertThrows<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Buffer(Return42, -1));
-            AssertThrows<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Buffer(Return42, -1, 1));
-            AssertThrows<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Buffer(Return42, 1, -1));
+            Assert.Throws<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Buffer(Return42, -1));
+            Assert.Throws<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Buffer(Return42, -1, 1));
+            Assert.Throws<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Buffer(Return42, 1, -1));
         }
 
         [Fact]
-        public void Buffer1()
+        public async Task Buffer1Async()
         {
             var xs = new[] { 1, 2, 3, 4, 5 }.ToAsyncEnumerable().Buffer(2);
 
             var e = xs.GetAsyncEnumerator();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.True(e.Current.SequenceEqual(new[] { 1, 2 }));
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.True(e.Current.SequenceEqual(new[] { 3, 4 }));
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.True(e.Current.SequenceEqual(new[] { 5 }));
 
-            Assert.False(e.MoveNextAsync().Result);
+            Assert.False(await e.MoveNextAsync());
         }
 
         [Fact]
-        public void Buffer2()
+        public async Task Buffer2Async()
         {
             var xs = new[] { 1, 2, 3, 4, 5 }.ToAsyncEnumerable().Buffer(3, 2);
 
             var e = xs.GetAsyncEnumerator();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.True(e.Current.SequenceEqual(new[] { 1, 2, 3 }));
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.True(e.Current.SequenceEqual(new[] { 3, 4, 5 }));
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.True(e.Current.SequenceEqual(new[] { 5 }));
 
-            Assert.False(e.MoveNextAsync().Result);
+            Assert.False(await e.MoveNextAsync());
         }
 
         [Fact]
-        public void Buffer3()
+        public async Task Buffer3Async()
         {
             var xs = new[] { 1, 2, 3, 4, 5 }.ToAsyncEnumerable().Buffer(2, 3);
 
             var e = xs.GetAsyncEnumerator();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.True(e.Current.SequenceEqual(new[] { 1, 2 }));
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.True(e.Current.SequenceEqual(new[] { 4, 5 }));
 
-            Assert.False(e.MoveNextAsync().Result);
+            Assert.False(await e.MoveNextAsync());
         }
 
         [Fact]

+ 89 - 88
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Catch.cs

@@ -15,17 +15,17 @@ namespace Tests
         [Fact]
         public void Catch_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int, Exception>(default, x => default(IAsyncEnumerable<int>)));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int, Exception>(Return42, default(Func<Exception, IAsyncEnumerable<int>>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int, Exception>(default, x => default(IAsyncEnumerable<int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int, Exception>(Return42, default(Func<Exception, IAsyncEnumerable<int>>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int>(default, Return42));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int>(Return42, default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int>(default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int>(default(IEnumerable<IAsyncEnumerable<int>>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int>(default, Return42));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int>(Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int>(default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Catch<int>(default(IEnumerable<IAsyncEnumerable<int>>)));
         }
 
         [Fact]
-        public void Catch1()
+        public async Task Catch1Async()
         {
             var err = false;
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
@@ -34,16 +34,16 @@ namespace Tests
             var res = xs.Catch<int, Exception>(ex_ => { err = true; return ys; });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await NoNextAsync(e);
 
             Assert.False(err);
         }
 
         [Fact]
-        public void Catch2()
+        public async Task Catch2Async()
         {
             var ex = new InvalidOperationException("Bang!");
 
@@ -54,23 +54,23 @@ namespace Tests
             var res = xs.Catch<int, InvalidOperationException>(ex_ => { err = true; return ys; });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
 
             Assert.False(err);
 
-            HasNext(e, 4);
+            await HasNextAsync(e, 4);
 
             Assert.True(err);
 
-            HasNext(e, 5);
-            HasNext(e, 6);
-            NoNext(e);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Catch3()
+        public async Task Catch3Async()
         {
             var ex = new InvalidOperationException("Bang!");
 
@@ -81,23 +81,23 @@ namespace Tests
             var res = xs.Catch<int, Exception>(ex_ => { err = true; return ys; });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
 
             Assert.False(err);
 
-            HasNext(e, 4);
+            await HasNextAsync(e, 4);
 
             Assert.True(err);
 
-            HasNext(e, 5);
-            HasNext(e, 6);
-            NoNext(e);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Catch4()
+        public async Task Catch4Async()
         {
             var ex = new DivideByZeroException();
 
@@ -108,17 +108,17 @@ namespace Tests
             var res = xs.Catch<int, InvalidOperationException>(ex_ => { err = true; return ys; });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
 
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
 
             Assert.False(err);
         }
 
         [Fact]
-        public void Catch5()
+        public async Task Catch5Async()
         {
             var ex = new InvalidOperationException("Bang!");
             var ex2 = new Exception("Oops!");
@@ -129,15 +129,15 @@ namespace Tests
             var res = xs.Catch<int, InvalidOperationException>(ex_ => { if (ex_.Message == "Bang!") throw ex2; return ys; });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
 
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex2));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex2);
         }
 
         [Fact]
-        public void Catch6()
+        public async Task Catch6Async()
         {
             var ex = new InvalidOperationException("Bang!");
 
@@ -147,24 +147,24 @@ namespace Tests
             var res = xs.Catch<int, InvalidOperationException>(ex_ => { err = true; return xs; });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
 
             Assert.False(err);
 
-            HasNext(e, 1);
+            await HasNextAsync(e, 1);
 
             Assert.True(err);
 
-            HasNext(e, 2);
-            HasNext(e, 3);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
 
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Catch7()
+        public async Task Catch7Async()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
             var ys = new[] { 4, 5, 6 }.ToAsyncEnumerable();
@@ -172,14 +172,14 @@ namespace Tests
             var res = AsyncEnumerableEx.Catch(xs, ys);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Catch8()
+        public async Task Catch8Async()
         {
             var ex = new InvalidOperationException("Bang!");
 
@@ -189,17 +189,17 @@ namespace Tests
             var res = AsyncEnumerableEx.Catch(xs, ys);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Catch9()
+        public async Task Catch9Async()
         {
             var ex = new InvalidOperationException("Bang!");
 
@@ -209,39 +209,40 @@ namespace Tests
             var res = AsyncEnumerableEx.Catch(new[] { xs, xs, ys, ys });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Catch10()
+        public async Task Catch10Async()
         {
-            var res = CatchXss().Catch();
+            var ex = new Exception("Bang!");
+            var res = CatchXss(ex).Catch();
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
 
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single().Message == "Bang!");
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
-        private IEnumerable<IAsyncEnumerable<int>> CatchXss()
+        private IEnumerable<IAsyncEnumerable<int>> CatchXss(Exception ex)
         {
             yield return new[] { 1, 2, 3 }.ToAsyncEnumerable().Concat(Throw<int>(new Exception("!!!")));
-            throw new Exception("Bang!");
+            throw ex;
         }
 
         [Fact]
-        public void Catch11()
+        public async Task Catch11Async()
         {
             var ex = new InvalidOperationException("Bang!");
 
@@ -250,23 +251,23 @@ namespace Tests
             var res = AsyncEnumerableEx.Catch(new[] { xs, xs });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Catch12()
+        public async Task Catch12Async()
         {
             var res = AsyncEnumerableEx.Catch(Enumerable.Empty<IAsyncEnumerable<int>>());
 
             var e = res.GetAsyncEnumerator();
-            NoNext(e);
+            await NoNextAsync(e);
         }
 
         [Fact]

+ 30 - 29
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Concat.cs

@@ -15,12 +15,12 @@ namespace Tests
         [Fact]
         public void Concat_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Concat<int>(default(IAsyncEnumerable<int>[])));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Concat<int>(default(IEnumerable<IAsyncEnumerable<int>>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Concat<int>(default(IAsyncEnumerable<int>[])));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Concat<int>(default(IEnumerable<IAsyncEnumerable<int>>)));
         }
 
         [Fact]
-        public void Concat4()
+        public async Task Concat4Async()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
             var ys = new[] { 4, 5 }.ToAsyncEnumerable();
@@ -29,19 +29,19 @@ namespace Tests
             var res = AsyncEnumerableEx.Concat(xs, ys, zs);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            HasNext(e, 7);
-            HasNext(e, 8);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await HasNextAsync(e, 7);
+            await HasNextAsync(e, 8);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Concat5()
+        public async Task Concat5Async()
         {
             var ex = new Exception("Bang");
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
@@ -51,26 +51,27 @@ namespace Tests
             var res = AsyncEnumerableEx.Concat(xs, ys, zs);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Concat6()
+        public async Task Concat6Async()
         {
-            var res = AsyncEnumerableEx.Concat(ConcatXss());
+            var ex = new Exception("Bang");
+            var res = AsyncEnumerableEx.Concat(ConcatXss(ex));
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single().Message == "Bang!");
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
@@ -85,11 +86,11 @@ namespace Tests
             await SequenceIdentity(res);
         }
 
-        private static IEnumerable<IAsyncEnumerable<int>> ConcatXss()
+        private static IEnumerable<IAsyncEnumerable<int>> ConcatXss(Exception ex)
         {
             yield return new[] { 1, 2, 3 }.ToAsyncEnumerable();
             yield return new[] { 4, 5 }.ToAsyncEnumerable();
-            throw new Exception("Bang!");
+            throw ex;
         }
     }
 }

+ 7 - 6
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Defer.cs

@@ -5,6 +5,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 using Xunit;
 
 namespace Tests
@@ -14,26 +15,26 @@ namespace Tests
         [Fact]
         public void Defer_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Defer<int>(default(Func<IAsyncEnumerable<int>>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Defer<int>(default(Func<IAsyncEnumerable<int>>)));
         }
 
         [Fact]
-        public void Defer1()
+        public async Task Defer1Async()
         {
             var x = 0;
             var xs = AsyncEnumerableEx.Defer<int>(() => new[] { x }.ToAsyncEnumerable());
 
             {
                 var e = xs.GetAsyncEnumerator();
-                HasNext(e, 0);
-                NoNext(e);
+                await HasNextAsync(e, 0);
+                await NoNextAsync(e);
             }
 
             {
                 x++;
                 var e = xs.GetAsyncEnumerator();
-                HasNext(e, 1);
-                NoNext(e);
+                await HasNextAsync(e, 1);
+                await NoNextAsync(e);
             }
         }
     }

+ 12 - 13
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Distinct.cs

@@ -15,26 +15,25 @@ namespace Tests
         [Fact]
         public void Distinct_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Distinct<int, int>(Return42, default(Func<int, int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Distinct<int, int>(Return42, default(Func<int, int>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Distinct(default(IAsyncEnumerable<int>), x => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Distinct(Return42, default(Func<int, int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Distinct(default(IAsyncEnumerable<int>), x => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Distinct(Return42, default(Func<int, int>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Distinct(default(IAsyncEnumerable<int>), x => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Distinct(Return42, default(Func<int, int>), EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Distinct(Return42, x => x, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Distinct(default(IAsyncEnumerable<int>), x => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Distinct(Return42, default(Func<int, int>), EqualityComparer<int>.Default));
         }
 
         [Fact]
-        public void Distinct1()
+        public async Task Distinct1Async()
         {
             var xs = new[] { 1, 2, 3, 4, 5 }.ToAsyncEnumerable().Distinct(x => x / 2);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 4);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 4);
+            await NoNextAsync(e);
         }
 
         [Fact]
@@ -72,13 +71,13 @@ namespace Tests
         }
 
         [Fact]
-        public void Distinct11()
+        public async Task Distinct11Async()
         {
             var xs = AsyncEnumerable.Empty<int>().Distinct(k => k);
 
             var e = xs.GetAsyncEnumerator();
 
-            NoNext(e);
+            await NoNextAsync(e);
         }
     }
 }

+ 29 - 31
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/DistinctUntilChanged.cs

@@ -15,62 +15,60 @@ namespace Tests
         [Fact]
         public void DistinctUntilChanged_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(default(IAsyncEnumerable<int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(default(IAsyncEnumerable<int>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(default, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(default, EqualityComparer<int>.Default));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(default(IAsyncEnumerable<int>), x => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(Return42, default(Func<int, int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(default(IAsyncEnumerable<int>), x => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(Return42, default(Func<int, int>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(default(IAsyncEnumerable<int>), x => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(Return42, default(Func<int, int>), EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(Return42, x => x, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(default(IAsyncEnumerable<int>), x => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.DistinctUntilChanged(Return42, default(Func<int, int>), EqualityComparer<int>.Default));
         }
 
         [Fact]
-        public void DistinctUntilChanged1()
+        public async Task DistinctUntilChanged1Async()
         {
             var xs = new[] { 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 6, 7, 3, 2, 2, 1, 1 }.ToAsyncEnumerable().DistinctUntilChanged();
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            HasNext(e, 7);
-            HasNext(e, 3);
-            HasNext(e, 2);
-            HasNext(e, 1);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await HasNextAsync(e, 7);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 1);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void DistinctUntilChanged2()
+        public async Task DistinctUntilChanged2Async()
         {
             var xs = new[] { 1, 2, 3, 4, 3, 5, 2 }.ToAsyncEnumerable().DistinctUntilChanged(x => (x + 1) / 2);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 3);
-            HasNext(e, 5);
-            HasNext(e, 2);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 2);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void DistinctUntilChanged3()
+        public async Task DistinctUntilChanged3Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 1, 2, 3, 4, 3, 5, 2 }.ToAsyncEnumerable().DistinctUntilChanged(x => { if (x == 4) throw ex; return x; });
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]

+ 38 - 38
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Do.cs

@@ -15,58 +15,58 @@ namespace Tests
         [Fact]
         public void Do_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(default, x => { }));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, default(Action<int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(default, x => { }));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, default(Action<int>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(default, x => { }, () => { }));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, default, () => { }));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, x => { }, default(Action)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(default, x => { }, () => { }));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, default, () => { }));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, x => { }, default(Action)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(default, x => { }, ex => { }));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, default, ex => { }));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, x => { }, default(Action<Exception>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(default, x => { }, ex => { }));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, default, ex => { }));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, x => { }, default(Action<Exception>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(default, x => { }, ex => { }, () => { }));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, default, ex => { }, () => { }));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, x => { }, default, () => { }));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, x => { }, ex => { }, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(default, x => { }, ex => { }, () => { }));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, default, ex => { }, () => { }));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, x => { }, default, () => { }));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, x => { }, ex => { }, default));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(default, new MyObs()));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, default(IObserver<int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(default, new MyObs()));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(Return42, default(IObserver<int>)));
         }
 
         [Fact]
-        public void Do1()
+        public async Task Do1Async()
         {
             var sum = 0;
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
             var ys = xs.Do(x => sum += x);
 
             var e = ys.GetAsyncEnumerator();
-            HasNext(e, 1);
+            await HasNextAsync(e, 1);
             Assert.Equal(1, sum);
-            HasNext(e, 2);
+            await HasNextAsync(e, 2);
             Assert.Equal(3, sum);
-            HasNext(e, 3);
+            await HasNextAsync(e, 3);
             Assert.Equal(6, sum);
-            HasNext(e, 4);
+            await HasNextAsync(e, 4);
             Assert.Equal(10, sum);
-            NoNext(e);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Do2()
+        public async Task Do2()
         {
             var ex = new Exception("Bang");
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
             var ys = xs.Do(x => { throw ex; });
 
             var e = ys.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Do3()
+        public async Task Do3Async()
         {
             var sum = 0;
             var fail = false;
@@ -75,22 +75,22 @@ namespace Tests
             var ys = xs.Do(x => sum += x, ex => { fail = true; }, () => { done = true; });
 
             var e = ys.GetAsyncEnumerator();
-            HasNext(e, 1);
+            await HasNextAsync(e, 1);
             Assert.Equal(1, sum);
-            HasNext(e, 2);
+            await HasNextAsync(e, 2);
             Assert.Equal(3, sum);
-            HasNext(e, 3);
+            await HasNextAsync(e, 3);
             Assert.Equal(6, sum);
-            HasNext(e, 4);
+            await HasNextAsync(e, 4);
             Assert.Equal(10, sum);
-            NoNext(e);
+            await NoNextAsync(e);
 
             Assert.False(fail);
             Assert.True(done);
         }
 
         [Fact]
-        public void Do4()
+        public async Task Do4Async()
         {
             var sum = 0;
             var done = false;
@@ -98,21 +98,21 @@ namespace Tests
             var ys = xs.Do(x => sum += x, () => { done = true; });
 
             var e = ys.GetAsyncEnumerator();
-            HasNext(e, 1);
+            await HasNextAsync(e, 1);
             Assert.Equal(1, sum);
-            HasNext(e, 2);
+            await HasNextAsync(e, 2);
             Assert.Equal(3, sum);
-            HasNext(e, 3);
+            await HasNextAsync(e, 3);
             Assert.Equal(6, sum);
-            HasNext(e, 4);
+            await HasNextAsync(e, 4);
             Assert.Equal(10, sum);
-            NoNext(e);
+            await NoNextAsync(e);
 
             Assert.True(done);
         }
 
         [Fact]
-        public void Do5()
+        public async Task Do5()
         {
             var ex = new Exception("Bang");
             var exa = default(Exception);
@@ -122,7 +122,7 @@ namespace Tests
             var ys = xs.Do(x => { hasv = true; }, exx => { exa = exx; }, () => { done = true; });
 
             var e = ys.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ex_.InnerException == ex);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
 
             Assert.False(hasv);
             Assert.False(done);
@@ -130,7 +130,7 @@ namespace Tests
         }
 
         [Fact]
-        public void Do6()
+        public async Task Do6()
         {
             var ex = new Exception("Bang");
             var exa = default(Exception);
@@ -139,7 +139,7 @@ namespace Tests
             var ys = xs.Do(x => { hasv = true; }, exx => { exa = exx; });
 
             var e = ys.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ex_.InnerException == ex);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
 
             Assert.False(hasv);
             Assert.Same(exa, ex);

+ 17 - 17
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Expand.cs

@@ -15,45 +15,45 @@ namespace Tests
         [Fact]
         public void Expand_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Expand(default(IAsyncEnumerable<int>), x => default(IAsyncEnumerable<int>)));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Expand(Return42, default(Func<int, IAsyncEnumerable<int>>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Expand(default(IAsyncEnumerable<int>), x => default(IAsyncEnumerable<int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Expand(Return42, default(Func<int, IAsyncEnumerable<int>>)));
         }
 
         [Fact]
-        public void Expand1()
+        public async Task Expand1Async()
         {
             var xs = new[] { 2, 3 }.ToAsyncEnumerable().Expand(x => AsyncEnumerableEx.Return(x - 1).Repeat(x - 1));
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 2);
-            HasNext(e, 1);
-            HasNext(e, 1);
-            NoNext(e);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 1);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Expand2()
+        public async Task Expand2()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 2, 3 }.ToAsyncEnumerable().Expand(new Func<int, IAsyncEnumerable<int>>(x => { throw ex; }));
 
             var e = xs.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Expand3()
+        public async Task Expand3Async()
         {
             var xs = new[] { 2, 3 }.ToAsyncEnumerable().Expand(x => default(IAsyncEnumerable<int>));
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 2);
-            HasNext(e, 3);
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is NullReferenceException);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await AssertThrowsAsync<NullReferenceException>(e.MoveNextAsync().AsTask());
         }
 
         [Fact]

+ 14 - 14
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Finally.cs

@@ -15,12 +15,12 @@ namespace Tests
         [Fact]
         public void Finally_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Finally(default(IAsyncEnumerable<int>), () => { }));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Finally(Return42, default(Action)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Finally(default(IAsyncEnumerable<int>), () => { }));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Finally(Return42, default(Action)));
         }
 
         [Fact]
-        public void Finally1()
+        public async Task Finally1Async()
         {
             var b = false;
 
@@ -29,13 +29,13 @@ namespace Tests
             var e = xs.GetAsyncEnumerator();
 
             Assert.False(b);
-            NoNext(e);
+            await NoNextAsync(e);
 
             Assert.True(b);
         }
 
         [Fact]
-        public void Finally2()
+        public async Task Finally2Async()
         {
             var b = false;
 
@@ -44,16 +44,16 @@ namespace Tests
             var e = xs.GetAsyncEnumerator();
 
             Assert.False(b);
-            HasNext(e, 42);
+            await HasNextAsync(e, 42);
 
             Assert.False(b);
-            NoNext(e);
+            await NoNextAsync(e);
 
             Assert.True(b);
         }
 
         [Fact]
-        public void Finally3()
+        public async Task Finally3Async()
         {
             var ex = new Exception("Bang!");
 
@@ -64,13 +64,13 @@ namespace Tests
             var e = xs.GetAsyncEnumerator();
 
             Assert.False(b);
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
 
             Assert.True(b);
         }
 
         [Fact]
-        public void Finally4()
+        public async Task Finally4Async()
         {
             var b = false;
 
@@ -79,13 +79,13 @@ namespace Tests
             var e = xs.GetAsyncEnumerator();
 
             Assert.False(b);
-            HasNext(e, 1);
+            await HasNextAsync(e, 1);
 
             Assert.False(b);
-            HasNext(e, 2);
+            await HasNextAsync(e, 2);
 
             Assert.False(b);
-            NoNext(e);
+            await NoNextAsync(e);
 
             Assert.True(b);
         }
@@ -100,7 +100,7 @@ namespace Tests
             var e = xs.GetAsyncEnumerator();
 
             Assert.False(b);
-            HasNext(e, 1);
+            await HasNextAsync(e, 1);
 
             await e.DisposeAsync();
 

+ 17 - 17
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Generate.cs

@@ -14,9 +14,9 @@ namespace Tests
         [Fact]
         public void Generate_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Generate<int, int>(0, default, x => x, x => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Generate<int, int>(0, x => true, default, x => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Generate<int, int>(0, x => true, x => x, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Generate<int, int>(0, default, x => x, x => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Generate<int, int>(0, x => true, default, x => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Generate<int, int>(0, x => true, x => x, default));
         }
 
         [Fact]
@@ -25,45 +25,45 @@ namespace Tests
             var xs = AsyncEnumerableEx.Generate(0, x => x < 5, x => x + 1, x => x * x);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 0);
-            HasNext(e, 1);
-            HasNext(e, 4);
-            HasNext(e, 9);
-            HasNext(e, 16);
-            NoNext(e);
+            await HasNextAsync(e, 0);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 9);
+            await HasNextAsync(e, 16);
+            await NoNextAsync(e);
             await e.DisposeAsync();
         }
 
         [Fact]
-        public void Generate2()
+        public async Task Generate2Async()
         {
             var ex = new Exception("Bang!");
             var xs = AsyncEnumerableEx.Generate(0, x => { throw ex; }, x => x + 1, x => x * x);
 
             var e = xs.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Generate3()
+        public async Task Generate3Async()
         {
             var ex = new Exception("Bang!");
             var xs = AsyncEnumerableEx.Generate(0, x => true, x => x + 1, x => { if (x == 1) throw ex; return x * x; });
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 0);
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).InnerExceptions.Single() == ex);
+            await HasNextAsync(e, 0);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Generate4()
+        public async Task Generate4Async()
         {
             var ex = new Exception("Bang!");
             var xs = AsyncEnumerableEx.Generate(0, x => true, x => { throw ex; }, x => x * x);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 0);
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).InnerExceptions.Single() == ex);
+            await HasNextAsync(e, 0);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]

+ 9 - 15
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/IgnoreElements.cs

@@ -15,50 +15,44 @@ namespace Tests
         [Fact]
         public void IgnoreElements_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.IgnoreElements(default(IAsyncEnumerable<int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.IgnoreElements(default(IAsyncEnumerable<int>)));
         }
 
         [Fact]
-        public void IgnoreElements1()
+        public async Task IgnoreElements1Async()
         {
             var xs = AsyncEnumerable.Empty<int>().IgnoreElements();
 
             var e = xs.GetAsyncEnumerator();
-            NoNext(e);
-
-            AssertThrows<InvalidOperationException>(() => { var ignored = e.Current; });
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void IgnoreElements2()
+        public async Task IgnoreElements2Async()
         {
             var xs = Return42.IgnoreElements();
 
             var e = xs.GetAsyncEnumerator();
-            NoNext(e);
-
-            AssertThrows<InvalidOperationException>(() => { var ignored = e.Current; });
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void IgnoreElements3()
+        public async Task IgnoreElements3Async()
         {
             var xs = AsyncEnumerable.Range(0, 10).IgnoreElements();
 
             var e = xs.GetAsyncEnumerator();
-            NoNext(e);
-
-            AssertThrows<InvalidOperationException>(() => { var ignored = e.Current; });
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void IgnoreElements4()
+        public async Task IgnoreElements4Async()
         {
             var ex = new Exception("Bang!");
             var xs = Throw<int>(ex).IgnoreElements();
 
             var e = xs.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]

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

@@ -17,10 +17,8 @@ namespace Tests
         public async Task Max_Null()
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Max(default, Comparer<DateTime>.Default));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Max(AsyncEnumerable.Empty<DateTime>(), default));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Max(default, Comparer<DateTime>.Default, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Max(AsyncEnumerable.Empty<DateTime>(), default, CancellationToken.None));
         }
     }
 }

+ 10 - 12
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/MaxBy.cs

@@ -21,58 +21,56 @@ namespace Tests
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(default(IAsyncEnumerable<int>), x => x, Comparer<int>.Default));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(Return42, default(Func<int, int>), Comparer<int>.Default));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(Return42, x => x, default(IComparer<int>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(default(IAsyncEnumerable<int>), x => x, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(Return42, default(Func<int, int>), CancellationToken.None));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(default(IAsyncEnumerable<int>), x => x, Comparer<int>.Default, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(Return42, default(Func<int, int>), Comparer<int>.Default, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(Return42, x => x, default, CancellationToken.None));
         }
 
         [Fact]
-        public void MaxBy1()
+        public async Task MaxBy1Async()
         {
             var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MaxBy(x => x / 2);
-            var res = xs.Result;
+            var res = await xs;
 
             Assert.True(res.SequenceEqual(new[] { 7, 6 }));
         }
 
         [Fact]
-        public void MaxBy2()
+        public async Task MaxBy2()
         {
             var xs = new int[0].ToAsyncEnumerable().MaxBy(x => x / 2);
 
-            AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await AssertThrowsAsync<InvalidOperationException>(xs);
         }
 
         [Fact]
-        public void MaxBy3()
+        public async Task MaxBy3()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MaxBy(x => { if (x == 3) throw ex; return x; });
 
-            AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(xs, ex);
         }
 
         [Fact]
-        public void MaxBy4()
+        public async Task MaxBy4()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MaxBy(x => { if (x == 4) throw ex; return x; });
 
-            AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(xs, ex);
         }
 
         [Fact]
-        public void MaxBy5()
+        public async Task MaxBy5()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().Concat(Throw<int>(ex)).MaxBy(x => x, Comparer<int>.Default);
 
-            AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(xs, ex);
         }
     }
 }

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

@@ -17,10 +17,8 @@ namespace Tests
         public async Task Min_Null()
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Min(default, Comparer<DateTime>.Default));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Min(AsyncEnumerable.Empty<DateTime>(), default));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Min(default, Comparer<DateTime>.Default, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Min(AsyncEnumerable.Empty<DateTime>(), default, CancellationToken.None));
         }
     }
 }

+ 10 - 12
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/MinBy.cs

@@ -21,58 +21,56 @@ namespace Tests
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(default(IAsyncEnumerable<int>), x => x, Comparer<int>.Default));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(Return42, default(Func<int, int>), Comparer<int>.Default));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(Return42, x => x, default(IComparer<int>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(default(IAsyncEnumerable<int>), x => x, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(Return42, default(Func<int, int>), CancellationToken.None));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(default(IAsyncEnumerable<int>), x => x, Comparer<int>.Default, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(Return42, default(Func<int, int>), Comparer<int>.Default, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(Return42, x => x, default, CancellationToken.None));
         }
 
         [Fact]
-        public void MinBy1()
+        public async Task MinBy1Async()
         {
             var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MinBy(x => x / 2);
-            var res = xs.Result;
+            var res = await xs;
 
             Assert.True(res.SequenceEqual(new[] { 3, 2 }));
         }
 
         [Fact]
-        public void MinBy2()
+        public async Task MinBy2Async()
         {
             var xs = new int[0].ToAsyncEnumerable().MinBy(x => x / 2);
 
-            AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await AssertThrowsAsync<InvalidOperationException>(xs);
         }
 
         [Fact]
-        public void MinBy3()
+        public async Task MinBy3Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MinBy(x => { if (x == 3) throw ex; return x; });
 
-            AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(xs, ex);
         }
 
         [Fact]
-        public void MinBy4()
+        public async Task MinBy4Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MinBy(x => { if (x == 4) throw ex; return x; });
 
-            AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(xs, ex);
         }
 
         [Fact]
-        public void MinBy5()
+        public async Task MinBy5Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().Concat(Throw<int>(ex)).MinBy(x => x, Comparer<int>.Default);
 
-            AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(xs, ex);
         }
     }
 }

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

@@ -2,7 +2,6 @@
 // The .NET Foundation licenses this file to you under the Apache 2.0 License.
 // See the LICENSE file in the project root for more information. 
 
-using System;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -19,14 +18,9 @@ namespace Tests
 
             var e = xs.GetAsyncEnumerator();
             Assert.False(e.MoveNextAsync().IsCompleted); // Very rudimentary check
-            AssertThrows<InvalidOperationException>(() => Nop(e.Current));
             await e.DisposeAsync();
         }
 
-        private void Nop(object o)
-        {
-        }
-
         [Fact]
         public void CancelToken_Unblocks()
         {

+ 53 - 52
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/OnErrorResumeNext.cs

@@ -15,14 +15,14 @@ namespace Tests
         [Fact]
         public void OnErrorResumeNext_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.OnErrorResumeNext<int>(default, Return42));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.OnErrorResumeNext<int>(Return42, default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.OnErrorResumeNext<int>(default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.OnErrorResumeNext<int>(default(IEnumerable<IAsyncEnumerable<int>>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.OnErrorResumeNext<int>(default, Return42));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.OnErrorResumeNext<int>(Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.OnErrorResumeNext<int>(default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.OnErrorResumeNext<int>(default(IEnumerable<IAsyncEnumerable<int>>)));
         }
 
         [Fact]
-        public void OnErrorResumeNext7()
+        public async Task OnErrorResumeNext7Async()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
             var ys = new[] { 4, 5, 6 }.ToAsyncEnumerable();
@@ -30,17 +30,17 @@ namespace Tests
             var res = AsyncEnumerableEx.OnErrorResumeNext(xs, ys);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void OnErrorResumeNext8()
+        public async Task OnErrorResumeNext8Async()
         {
             var ex = new InvalidOperationException("Bang!");
 
@@ -50,17 +50,17 @@ namespace Tests
             var res = AsyncEnumerableEx.OnErrorResumeNext(xs, ys);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void OnErrorResumeNext9()
+        public async Task OnErrorResumeNext9Async()
         {
             var ex = new InvalidOperationException("Bang!");
 
@@ -70,42 +70,43 @@ namespace Tests
             var res = AsyncEnumerableEx.OnErrorResumeNext(new[] { xs, xs, ys, ys });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void OnErrorResumeNext10()
+        public async Task OnErrorResumeNext10Async()
         {
-            var res = OnErrorResumeNextXss().OnErrorResumeNext();
+            var ex = new Exception("Bang!");
+            var res = OnErrorResumeNextXss(ex).OnErrorResumeNext();
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
 
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single().Message == "Bang!");
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
-        private IEnumerable<IAsyncEnumerable<int>> OnErrorResumeNextXss()
+        private IEnumerable<IAsyncEnumerable<int>> OnErrorResumeNextXss(Exception ex)
         {
             yield return new[] { 1, 2, 3 }.ToAsyncEnumerable().Concat(Throw<int>(new Exception("!!!")));
-            throw new Exception("Bang!");
+            throw ex;
         }
 
         [Fact]
-        public void OnErrorResumeNext11()
+        public async Task OnErrorResumeNext11Async()
         {
             var ex = new InvalidOperationException("Bang!");
 
@@ -114,22 +115,22 @@ namespace Tests
             var res = AsyncEnumerableEx.OnErrorResumeNext(new[] { xs, xs });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void OnErrorResumeNext12()
+        public async Task OnErrorResumeNext12Async()
         {
             var res = AsyncEnumerableEx.OnErrorResumeNext(Enumerable.Empty<IAsyncEnumerable<int>>());
 
             var e = res.GetAsyncEnumerator();
-            NoNext(e);
+            await NoNextAsync(e);
         }
 
         [Fact]

+ 43 - 43
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Repeat.cs

@@ -18,11 +18,11 @@ namespace Tests
             var xs = AsyncEnumerableEx.Repeat(2);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 2);
-            HasNext(e, 2);
-            HasNext(e, 2);
-            HasNext(e, 2);
-            HasNext(e, 2);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 2);
             await e.DisposeAsync();
         }
 
@@ -37,73 +37,73 @@ namespace Tests
         [Fact]
         public void RepeatSequence_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Repeat(default(IAsyncEnumerable<int>)));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Repeat(default(IAsyncEnumerable<int>), 3));
-            AssertThrows<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Repeat(Return42, -1));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Repeat(default(IAsyncEnumerable<int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Repeat(default(IAsyncEnumerable<int>), 3));
+            Assert.Throws<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Repeat(Return42, -1));
         }
 
         [Fact]
-        public void RepeatSequence1()
+        public async Task RepeatSequence1Async()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable().Repeat();
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
         }
 
         [Fact]
-        public void RepeatSequence2()
+        public async Task RepeatSequence2Async()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable().Repeat(3);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void RepeatSequence3()
+        public async Task RepeatSequence3Async()
         {
             var i = 0;
             var xs = RepeatXs(() => i++).ToAsyncEnumerable().Repeat(3);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await NoNextAsync(e);
 
             Assert.Equal(3, i);
         }
 
         [Fact]
-        public void RepeatSequence4()
+        public async Task RepeatSequence4Async()
         {
             var i = 0;
             var xs = RepeatXs(() => i++).ToAsyncEnumerable().Repeat(0);
 
             var e = xs.GetAsyncEnumerator();
 
-            NoNext(e);
+            await NoNextAsync(e);
         }
 
         [Fact]
@@ -115,21 +115,21 @@ namespace Tests
         }
 
         [Fact]
-        public void RepeatSequence6()
+        public async Task RepeatSequence6Async()
         {
             var xs = new FailRepeat().ToAsyncEnumerable().Repeat();
 
             var e = xs.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is NotImplementedException);
+            await AssertThrowsAsync<NotImplementedException>(e.MoveNextAsync().AsTask());
         }
 
         [Fact]
-        public void RepeatSequence7()
+        public async Task RepeatSequence7Async()
         {
             var xs = new FailRepeat().ToAsyncEnumerable().Repeat(3);
 
             var e = xs.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is NotImplementedException);
+            await AssertThrowsAsync<NotImplementedException>(e.MoveNextAsync().AsTask());
         }
 
         private static IEnumerable<int> RepeatXs(Action started)

+ 19 - 18
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Retry.cs

@@ -5,6 +5,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 using Xunit;
 
 namespace Tests
@@ -14,28 +15,28 @@ namespace Tests
         [Fact]
         public void Retry_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Retry<int>(default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Retry<int>(default));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Retry<int>(default, 1));
-            AssertThrows<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Retry<int>(Return42, -1));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Retry<int>(default, 1));
+            Assert.Throws<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Retry<int>(Return42, -1));
         }
 
         [Fact]
-        public void Retry1()
+        public async Task Retry1Async()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
 
             var res = xs.Retry();
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Retry2()
+        public async Task Retry2Async()
         {
             var ex = new InvalidOperationException("Bang!");
 
@@ -44,15 +45,15 @@ namespace Tests
             var res = xs.Retry();
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
         }
     }
 }

+ 3 - 2
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Return.cs

@@ -3,6 +3,7 @@
 // See the LICENSE file in the project root for more information. 
 
 using System.Linq;
+using System.Threading.Tasks;
 using Xunit;
 
 namespace Tests
@@ -10,10 +11,10 @@ namespace Tests
     public class Return : AsyncEnumerableExTests
     {
         [Fact]
-        public void Return1()
+        public async Task Return1Async()
         {
             var xs = AsyncEnumerableEx.Return(42);
-            HasNext(xs.GetAsyncEnumerator(), 42);
+            await HasNextAsync(xs.GetAsyncEnumerator(), 42);
         }
     }
 }

+ 17 - 17
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Scan.cs

@@ -15,54 +15,54 @@ namespace Tests
         [Fact]
         public void Scan_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Scan(default(IAsyncEnumerable<int>), 3, (x, y) => x + y));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Scan(Return42, 3, default(Func<int, int, int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Scan(default(IAsyncEnumerable<int>), 3, (x, y) => x + y));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Scan(Return42, 3, default(Func<int, int, int>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Scan(default(IAsyncEnumerable<int>), (x, y) => x + y));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Scan(Return42, default(Func<int, int, int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Scan(default(IAsyncEnumerable<int>), (x, y) => x + y));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Scan(Return42, default(Func<int, int, int>)));
         }
 
         [Fact]
-        public void Scan1()
+        public async Task Scan1Async()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable().Scan(8, (x, y) => x + y);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 9);
-            HasNext(e, 11);
-            HasNext(e, 14);
-            NoNext(e);
+            await HasNextAsync(e, 9);
+            await HasNextAsync(e, 11);
+            await HasNextAsync(e, 14);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Scan2()
+        public async Task Scan2Async()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable().Scan((x, y) => x + y);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 3);
-            HasNext(e, 6);
-            NoNext(e);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 6);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Scan3()
+        public async Task Scan3()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable().Scan(8, new Func<int, int, int>((x, y) => { throw ex; }));
 
             var e = xs.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Scan4()
+        public async Task Scan4()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable().Scan(new Func<int, int, int>((x, y) => { throw ex; }));
 
             var e = xs.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]

+ 11 - 11
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/SelectMany.cs

@@ -3,8 +3,8 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 using Xunit;
 
 namespace Tests
@@ -14,12 +14,12 @@ namespace Tests
         [Fact]
         public void SelectMany_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.SelectMany<int, int>(default, Return42));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.SelectMany<int, int>(Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.SelectMany<int, int>(default, Return42));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.SelectMany<int, int>(Return42, default));
         }
 
         [Fact]
-        public void SelectMany1()
+        public async Task SelectMany1Async()
         {
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
             var ys = new[] { 3, 4 }.ToAsyncEnumerable();
@@ -27,13 +27,13 @@ namespace Tests
             var res = xs.SelectMany(ys);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            NoNext(e);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await NoNextAsync(e);
         }
     }
 }

+ 16 - 16
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/StartWith.cs

@@ -3,8 +3,8 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 using Xunit;
 
 namespace Tests
@@ -14,43 +14,43 @@ namespace Tests
         [Fact]
         public void StartWith_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.StartWith(default, new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.StartWith(Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.StartWith(default, new[] { 1 }));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.StartWith(Return42, default));
         }
 
         [Fact]
-        public void StartWith1()
+        public async Task StartWith1Async()
         {
             var xs = AsyncEnumerable.Empty<int>().StartWith(1, 2);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void StartWith2()
+        public async Task StartWith2Async()
         {
             var xs = Return42.StartWith(40, 41);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 40);
-            HasNext(e, 41);
-            HasNext(e, 42);
-            NoNext(e);
+            await HasNextAsync(e, 40);
+            await HasNextAsync(e, 41);
+            await HasNextAsync(e, 42);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void StartWith3()
+        public async Task StartWith3Async()
         {
             var ex = new Exception("Bang!");
             var xs = Throw<int>(ex).StartWith(1, 2);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
     }
 }

+ 37 - 16
Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/Using.cs

@@ -15,8 +15,8 @@ namespace Tests
         [Fact]
         public void Using_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Using<int, IDisposable>(default, _ => default(IAsyncEnumerable<int>)));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Using<int, IDisposable>(() => new MyD(null), default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Using<int, IDisposable>(default, _ => default(IAsyncEnumerable<int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Using<int, IDisposable>(() => new MyD(null), default));
         }
 
         [Fact]
@@ -35,9 +35,12 @@ namespace Tests
             );
 
             Assert.Equal(0, i);
+            Assert.Equal(0, d);
 
             var e = xs.GetAsyncEnumerator();
-            Assert.Equal(1, i);
+
+            Assert.Equal(0, i);
+            Assert.Equal(0, d);
         }
 
         [Fact]
@@ -56,16 +59,20 @@ namespace Tests
             );
 
             Assert.Equal(0, i);
+            Assert.Equal(0, d);
 
             var e = xs.GetAsyncEnumerator();
-            Assert.Equal(1, i);
+            Assert.Equal(0, i);
+            Assert.Equal(0, d);
 
             await e.DisposeAsync();
-            Assert.Equal(1, d);
+
+            Assert.Equal(0, i);
+            Assert.Equal(0, d);
         }
 
         [Fact]
-        public void Using3()
+        public async Task Using3()
         {
             var ex = new Exception("Bang!");
             var i = 0;
@@ -81,14 +88,21 @@ namespace Tests
             );
 
             Assert.Equal(0, i);
+            Assert.Equal(0, d);
+
+            var e = xs.GetAsyncEnumerator();
+
+            Assert.Equal(0, i);
+            Assert.Equal(0, d);
 
-            AssertThrows<Exception>(() => xs.GetAsyncEnumerator(), ex_ => ex_ == ex);
+            await e.DisposeAsync();
 
-            Assert.Equal(1, d);
+            Assert.Equal(0, i);
+            Assert.Equal(0, d);
         }
 
         [Fact]
-        public void Using4()
+        public async Task Using4Async()
         {
             var i = 0;
             var disposed = new TaskCompletionSource<bool>();
@@ -105,16 +119,20 @@ namespace Tests
             Assert.Equal(0, i);
 
             var e = xs.GetAsyncEnumerator();
+
+            Assert.Equal(0, i);
+
+            await HasNextAsync(e, 42);
+
             Assert.Equal(1, i);
 
-            HasNext(e, 42);
-            NoNext(e);
+            await NoNextAsync(e);
 
-            Assert.True(disposed.Task.Result);
+            Assert.True(await disposed.Task);
         }
 
         [Fact]
-        public void Using5()
+        public async Task Using5Async()
         {
             var ex = new Exception("Bang!");
             var i = 0;
@@ -132,11 +150,14 @@ namespace Tests
             Assert.Equal(0, i);
 
             var e = xs.GetAsyncEnumerator();
-            Assert.Equal(1, i);
 
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            Assert.Equal(0, i);
+
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
+
+            Assert.Equal(1, i);
 
-            Assert.True(disposed.Task.Result);
+            Assert.True(await disposed.Task);
         }
 
         [Fact]

+ 0 - 110
Ix.NET/Source/System.Interactive.Async/AsyncIterator.cs

@@ -1,110 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the Apache 2.0 License.
-// See the LICENSE file in the project root for more information. 
-
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.Linq
-{
-    internal abstract class AsyncIterator<TSource> : IAsyncEnumerable<TSource>, IAsyncEnumerator<TSource>
-    {
-        private readonly int _threadId;
-
-        private bool _currentIsInvalid = true;
-
-        internal TSource current;
-        internal AsyncIteratorState state = AsyncIteratorState.New;
-        internal CancellationToken token;
-
-        protected AsyncIterator()
-        {
-            _threadId = Environment.CurrentManagedThreadId;
-        }
-
-        public IAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken token)
-        {
-            var enumerator = state == AsyncIteratorState.New && _threadId == Environment.CurrentManagedThreadId
-                ? this
-                : Clone();
-
-            enumerator.state = AsyncIteratorState.Allocated;
-            enumerator.token = token;
-
-            try
-            {
-                enumerator.OnGetEnumerator(token);
-            }
-            catch
-            {
-                enumerator.DisposeAsync(); // REVIEW: fire-and-forget?
-                throw;
-            }
-
-            return enumerator;
-        }
-
-        public virtual ValueTask DisposeAsync()
-        {
-            current = default;
-            state = AsyncIteratorState.Disposed;
-
-            return TaskExt.CompletedTask;
-        }
-
-        public TSource Current
-        {
-            get
-            {
-                if (_currentIsInvalid)
-                    throw new InvalidOperationException("Enumerator is in an invalid state");
-
-                return current;
-            }
-        }
-
-        public async ValueTask<bool> MoveNextAsync()
-        {
-            // Note: MoveNext *must* be implemented as an async method to ensure
-            // that any exceptions thrown from the MoveNextCore call are handled 
-            // by the try/catch, whether they're sync or async
-
-            if (state == AsyncIteratorState.Disposed)
-            {
-                return false;
-            }
-
-            try
-            {
-                var result = await MoveNextCore(token).ConfigureAwait(false);
-
-                _currentIsInvalid = !result; // if move next is false, invalid otherwise valid
-
-                return result;
-            }
-            catch
-            {
-                _currentIsInvalid = true;
-                await DisposeAsync().ConfigureAwait(false);
-                throw;
-            }
-        }
-
-        public abstract AsyncIterator<TSource> Clone();
-
-        protected abstract ValueTask<bool> MoveNextCore(CancellationToken cancellationToken);
-
-        protected virtual void OnGetEnumerator(CancellationToken cancellationToken)
-        {
-        }
-    }
-
-    internal enum AsyncIteratorState
-    {
-        New = 0,
-        Allocated = 1,
-        Iterating = 2,
-        Disposed = -1,
-    }
-}

+ 7 - 0
Ix.NET/Source/System.Interactive.Async/System.Interactive.Async.csproj

@@ -7,6 +7,13 @@
     <PackageTags>Ix;Interactive;Extensions;Enumerable;Asynchronous</PackageTags>
   </PropertyGroup>
 
+  <ItemGroup>
+    <Compile Include="..\System.Linq.Async\System\Error.cs" Link="System\Error.cs" />
+    <Compile Include="..\System.Linq.Async\System\Linq\AsyncIterator.cs" Link="System\Linq\AsyncIterator.cs" />
+    <Compile Include="..\System.Linq.Async\System\Linq\Set.cs" Link="System\Linq\Set.cs" />
+    <Compile Include="..\System.Linq.Async\System\Strings.cs" Link="System\Strings.cs" />
+  </ItemGroup>
+
   <ItemGroup>
     <EmbeddedResource Include="Properties\System.Interactive.Async.rd.xml" />
   </ItemGroup>

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

@@ -14,9 +14,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Amb<TSource>(this IAsyncEnumerable<TSource> first, IAsyncEnumerable<TSource> second)
         {
             if (first == null)
-                throw new ArgumentNullException(nameof(first));
+                throw Error.ArgumentNull(nameof(first));
             if (second == null)
-                throw new ArgumentNullException(nameof(second));
+                throw Error.ArgumentNull(nameof(second));
 
             return new AmbAsyncIterator<TSource>(first, second);
         }
@@ -24,7 +24,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Amb<TSource>(params IAsyncEnumerable<TSource>[] sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return new AmbAsyncIteratorN<TSource>(sources);
         }
@@ -32,7 +32,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Amb<TSource>(this IEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return new AmbAsyncIteratorN<TSource>(sources.ToArray());
         }
@@ -69,13 +69,13 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        var firstEnumerator = _first.GetAsyncEnumerator(cancellationToken);
-                        var secondEnumerator = _second.GetAsyncEnumerator(cancellationToken);
+                        var firstEnumerator = _first.GetAsyncEnumerator(_cancellationToken);
+                        var secondEnumerator = _second.GetAsyncEnumerator(_cancellationToken);
 
                         var firstMoveNext = firstEnumerator.MoveNextAsync().AsTask();
                         var secondMoveNext = secondEnumerator.MoveNextAsync().AsTask();
@@ -110,11 +110,11 @@ namespace System.Linq
                             });
                         }
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
 
                         if (await winner.ConfigureAwait(false))
                         {
-                            current = _enumerator.Current;
+                            _current = _enumerator.Current;
                             return true;
                         }
 
@@ -123,7 +123,7 @@ namespace System.Linq
                     case AsyncIteratorState.Iterating:
                         if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                         {
-                            current = _enumerator.Current;
+                            _current = _enumerator.Current;
                             return true;
                         }
 
@@ -164,9 +164,9 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
                         var n = _sources.Length;
@@ -176,7 +176,7 @@ namespace System.Linq
 
                         for (var i = 0; i < n; i++)
                         {
-                            var enumerator = _sources[i].GetAsyncEnumerator(cancellationToken);
+                            var enumerator = _sources[i].GetAsyncEnumerator(_cancellationToken);
 
                             enumerators[i] = enumerator;
                             moveNexts[i] = enumerator.MoveNextAsync();
@@ -208,11 +208,11 @@ namespace System.Linq
                             }
                         }
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
 
                         if (await winner.ConfigureAwait(false))
                         {
-                            current = _enumerator.Current;
+                            _current = _enumerator.Current;
                             return true;
                         }
 
@@ -221,7 +221,7 @@ namespace System.Linq
                     case AsyncIteratorState.Iterating:
                         if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                         {
-                            current = _enumerator.Current;
+                            _current = _enumerator.Current;
                             return true;
                         }
 

+ 11 - 24
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Buffer.cs

@@ -14,14 +14,9 @@ namespace System.Linq
         public static IAsyncEnumerable<IList<TSource>> Buffer<TSource>(this IAsyncEnumerable<TSource> source, int count)
         {
             if (source == null)
-            {
-                throw new ArgumentNullException(nameof(source));
-            }
-
+                throw Error.ArgumentNull(nameof(source));
             if (count <= 0)
-            {
-                throw new ArgumentOutOfRangeException(nameof(count));
-            }
+                throw Error.ArgumentOutOfRange(nameof(count));
 
             return new BufferAsyncIterator<TSource>(source, count, count);
         }
@@ -29,19 +24,11 @@ namespace System.Linq
         public static IAsyncEnumerable<IList<TSource>> Buffer<TSource>(this IAsyncEnumerable<TSource> source, int count, int skip)
         {
             if (source == null)
-            {
-                throw new ArgumentNullException(nameof(source));
-            }
-
+                throw Error.ArgumentNull(nameof(source));
             if (count <= 0)
-            {
-                throw new ArgumentOutOfRangeException(nameof(count));
-            }
-
+                throw Error.ArgumentOutOfRange(nameof(count));
             if (skip <= 0)
-            {
-                throw new ArgumentOutOfRangeException(nameof(skip));
-            }
+                throw Error.ArgumentOutOfRange(nameof(skip));
 
             return new BufferAsyncIterator<TSource>(source, count, skip);
         }
@@ -84,17 +71,17 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
                         _buffers = new Queue<IList<TSource>>();
                         _index = 0;
                         _stopped = false;
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -117,7 +104,7 @@ namespace System.Linq
 
                                     if (_buffers.Count > 0 && _buffers.Peek().Count == _count)
                                     {
-                                        current = _buffers.Dequeue();
+                                        _current = _buffers.Dequeue();
                                         return true;
                                     }
 
@@ -133,7 +120,7 @@ namespace System.Linq
 
                             if (_buffers.Count > 0)
                             {
-                                current = _buffers.Dequeue();
+                                _current = _buffers.Dequeue();
                                 return true;
                             }
 

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

@@ -16,9 +16,9 @@ namespace System.Linq
             where TException : Exception
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (handler == null)
-                throw new ArgumentNullException(nameof(handler));
+                throw Error.ArgumentNull(nameof(handler));
 
             return new CatchAsyncIterator<TSource, TException>(source, handler);
         }
@@ -27,9 +27,9 @@ namespace System.Linq
             where TException : Exception
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (handler == null)
-                throw new ArgumentNullException(nameof(handler));
+                throw Error.ArgumentNull(nameof(handler));
 
             return new CatchAsyncIteratorWithTask<TSource, TException>(source, handler);
         }
@@ -37,7 +37,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Catch<TSource>(this IEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return CatchCore(sources);
         }
@@ -45,7 +45,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Catch<TSource>(params IAsyncEnumerable<TSource>[] sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return CatchCore(sources);
         }
@@ -53,9 +53,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Catch<TSource>(this IAsyncEnumerable<TSource> first, IAsyncEnumerable<TSource> second)
         {
             if (first == null)
-                throw new ArgumentNullException(nameof(first));
+                throw Error.ArgumentNull(nameof(first));
             if (second == null)
-                throw new ArgumentNullException(nameof(second));
+                throw Error.ArgumentNull(nameof(second));
 
             return CatchCore(new[] { first, second });
         }
@@ -98,15 +98,15 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
                         _isDone = false;
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -118,7 +118,7 @@ namespace System.Linq
                                 {
                                     if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                                     {
-                                        current = _enumerator.Current;
+                                        _current = _enumerator.Current;
                                         return true;
                                     }
                                 }
@@ -128,7 +128,7 @@ namespace System.Linq
                                     // invoking the handler, but we use this order to preserve
                                     // current behavior
                                     var inner = _handler(ex);
-                                    var err = inner.GetAsyncEnumerator(cancellationToken);
+                                    var err = inner.GetAsyncEnumerator(_cancellationToken);
 
                                     if (_enumerator != null)
                                     {
@@ -143,7 +143,7 @@ namespace System.Linq
 
                             if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                             {
-                                current = _enumerator.Current;
+                                _current = _enumerator.Current;
                                 return true;
                             }
 
@@ -191,15 +191,15 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
                         _isDone = false;
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -211,7 +211,7 @@ namespace System.Linq
                                 {
                                     if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                                     {
-                                        current = _enumerator.Current;
+                                        _current = _enumerator.Current;
                                         return true;
                                     }
                                 }
@@ -221,7 +221,7 @@ namespace System.Linq
                                     // invoking the handler, but we use this order to preserve
                                     // current behavior
                                     var inner = await _handler(ex).ConfigureAwait(false);
-                                    var err = inner.GetAsyncEnumerator(cancellationToken);
+                                    var err = inner.GetAsyncEnumerator(_cancellationToken);
 
                                     if (_enumerator != null)
                                     {
@@ -236,7 +236,7 @@ namespace System.Linq
 
                             if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                             {
-                                current = _enumerator.Current;
+                                _current = _enumerator.Current;
                                 return true;
                             }
 
@@ -291,14 +291,14 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
                         _sourcesEnumerator = _sources.GetEnumerator();
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -314,14 +314,14 @@ namespace System.Linq
                                 }
 
                                 _error = null;
-                                _enumerator = _sourcesEnumerator.Current.GetAsyncEnumerator(cancellationToken);
+                                _enumerator = _sourcesEnumerator.Current.GetAsyncEnumerator(_cancellationToken);
                             }
 
                             try
                             {
                                 if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                                 {
-                                    current = _enumerator.Current;
+                                    _current = _enumerator.Current;
                                     return true;
                                 }
                             }

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

@@ -14,7 +14,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Concat<TSource>(this IAsyncEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return new ConcatAsyncEnumerableAsyncIterator<TSource>(sources);
         }
@@ -22,7 +22,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Concat<TSource>(this IEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return ConcatCore(sources);
         }
@@ -30,7 +30,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Concat<TSource>(params IAsyncEnumerable<TSource>[] sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return ConcatCore(sources);
         }
@@ -81,14 +81,14 @@ namespace System.Linq
             private const int State_OuterNext = 1;
             private const int State_While = 4;
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
                         _outerEnumerator = _source.GetEnumerator();
                         _mode = State_OuterNext;
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -103,7 +103,7 @@ namespace System.Linq
                                         await _currentEnumerator.DisposeAsync().ConfigureAwait(false);
                                     }
 
-                                    _currentEnumerator = _outerEnumerator.Current.GetAsyncEnumerator(cancellationToken);
+                                    _currentEnumerator = _outerEnumerator.Current.GetAsyncEnumerator(_cancellationToken);
 
                                     _mode = State_While;
                                     goto case State_While;
@@ -113,7 +113,7 @@ namespace System.Linq
                             case State_While:
                                 if (await _currentEnumerator.MoveNextAsync().ConfigureAwait(false))
                                 {
-                                    current = _currentEnumerator.Current;
+                                    _current = _currentEnumerator.Current;
                                     return true;
                                 }
 
@@ -170,14 +170,14 @@ namespace System.Linq
             private const int State_OuterNext = 1;
             private const int State_While = 4;
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _outerEnumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _outerEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
                         _mode = State_OuterNext;
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -192,7 +192,7 @@ namespace System.Linq
                                         await _currentEnumerator.DisposeAsync().ConfigureAwait(false);
                                     }
 
-                                    _currentEnumerator = _outerEnumerator.Current.GetAsyncEnumerator(cancellationToken);
+                                    _currentEnumerator = _outerEnumerator.Current.GetAsyncEnumerator(_cancellationToken);
 
                                     _mode = State_While;
                                     goto case State_While;
@@ -202,7 +202,7 @@ namespace System.Linq
                             case State_While:
                                 if (await _currentEnumerator.MoveNextAsync().ConfigureAwait(false))
                                 {
-                                    current = _currentEnumerator.Current;
+                                    _current = _currentEnumerator.Current;
                                     return true;
                                 }
 

+ 96 - 3
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Defer.cs

@@ -3,6 +3,8 @@
 // See the LICENSE file in the project root for more information. 
 
 using System.Collections.Generic;
+using System.Diagnostics;
+using System.Threading;
 using System.Threading.Tasks;
 using static System.Linq.AsyncEnumerable;
 
@@ -13,7 +15,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Defer<TSource>(Func<IAsyncEnumerable<TSource>> factory)
         {
             if (factory == null)
-                throw new ArgumentNullException(nameof(factory));
+                throw Error.ArgumentNull(nameof(factory));
 
             return CreateEnumerable(ct => factory().GetAsyncEnumerator(ct));
         }
@@ -21,9 +23,100 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Defer<TSource>(Func<Task<IAsyncEnumerable<TSource>>> factory)
         {
             if (factory == null)
-                throw new ArgumentNullException(nameof(factory));
+                throw Error.ArgumentNull(nameof(factory));
 
-            return CreateEnumerable(async ct => (await factory().ConfigureAwait(false)).GetAsyncEnumerator(ct));
+            return new AnonymousAsyncEnumerableWithTask<TSource>(async ct => (await factory().ConfigureAwait(false)).GetAsyncEnumerator(ct));
         }
+
+        private sealed class AnonymousAsyncEnumerableWithTask<T> : IAsyncEnumerable<T>
+        {
+            private readonly Func<CancellationToken, Task<IAsyncEnumerator<T>>> _getEnumerator;
+
+            public AnonymousAsyncEnumerableWithTask(Func<CancellationToken, Task<IAsyncEnumerator<T>>> getEnumerator)
+            {
+                Debug.Assert(getEnumerator != null);
+
+                _getEnumerator = getEnumerator;
+            }
+
+            public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken) => new Enumerator(_getEnumerator, cancellationToken);
+
+            private sealed class Enumerator : IAsyncEnumerator<T>
+            {
+                private Func<CancellationToken, Task<IAsyncEnumerator<T>>> _getEnumerator;
+                private readonly CancellationToken _cancellationToken;
+                private IAsyncEnumerator<T> _enumerator;
+
+                public Enumerator(Func<CancellationToken, Task<IAsyncEnumerator<T>>> getEnumerator, CancellationToken cancellationToken)
+                {
+                    Debug.Assert(getEnumerator != null);
+
+                    _getEnumerator = getEnumerator;
+                    _cancellationToken = cancellationToken;
+                }
+
+                public T Current
+                {
+                    get
+                    {
+                        if (_enumerator == null)
+                            throw new InvalidOperationException();
+
+                        return _enumerator.Current;
+                    }
+                }
+
+                public async ValueTask DisposeAsync()
+                {
+                    var old = Interlocked.Exchange(ref _enumerator, DisposedEnumerator.Instance);
+
+                    if (_enumerator != null)
+                    {
+                        await _enumerator.DisposeAsync().ConfigureAwait(false);
+                    }
+                }
+
+                public ValueTask<bool> MoveNextAsync()
+                {
+                    if (_enumerator == null)
+                    {
+                        return InitAndMoveNextAsync();
+                    }
+
+                    return _enumerator.MoveNextAsync();
+                }
+
+                private async ValueTask<bool> InitAndMoveNextAsync()
+                {
+                    try
+                    {
+                        _enumerator = await _getEnumerator(_cancellationToken).ConfigureAwait(false);
+                    }
+                    catch (Exception ex)
+                    {
+                        _enumerator = Throw<T>(ex).GetAsyncEnumerator(_cancellationToken);
+                        throw;
+                    }
+                    finally
+                    {
+                        _getEnumerator = null;
+                    }
+
+                    return await _enumerator.MoveNextAsync().ConfigureAwait(false);
+                }
+
+                private sealed class DisposedEnumerator : IAsyncEnumerator<T>
+                {
+                    public static readonly DisposedEnumerator Instance = new DisposedEnumerator();
+
+                    public T Current => throw new ObjectDisposedException("this");
+
+                    public ValueTask DisposeAsync() => default;
+
+                    public ValueTask<bool> MoveNextAsync() => throw new ObjectDisposedException("this");
+                }
+            }
+        }
+
     }
 }

+ 25 - 29
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Distinct.cs

@@ -14,21 +14,19 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return DistinctCore(source, keySelector, EqualityComparer<TKey>.Default);
+            return DistinctCore(source, keySelector, comparer: null);
         }
 
         public static IAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(keySelector));
 
             return DistinctCore(source, keySelector, comparer);
         }
@@ -36,21 +34,21 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return DistinctCore(source, keySelector, EqualityComparer<TKey>.Default);
+            return DistinctCore<TSource, TKey>(source, keySelector, comparer: null);
         }
 
         public static IAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector, IEqualityComparer<TKey> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
             if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(comparer));
 
             return DistinctCore(source, keySelector, comparer);
         }
@@ -78,7 +76,6 @@ namespace System.Linq
             {
                 Debug.Assert(source != null);
                 Debug.Assert(keySelector != null);
-                Debug.Assert(comparer != null);
 
                 _source = source;
                 _keySelector = keySelector;
@@ -145,12 +142,12 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
 
                         if (!await _enumerator.MoveNextAsync().ConfigureAwait(false))
                         {
@@ -161,9 +158,9 @@ namespace System.Linq
                         var element = _enumerator.Current;
                         _set = new Set<TKey>(_comparer);
                         _set.Add(_keySelector(element));
-                        current = element;
+                        _current = element;
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         return true;
 
                     case AsyncIteratorState.Iterating:
@@ -172,7 +169,7 @@ namespace System.Linq
                             element = _enumerator.Current;
                             if (_set.Add(_keySelector(element)))
                             {
-                                current = element;
+                                _current = element;
                                 return true;
                             }
                         }
@@ -193,7 +190,7 @@ namespace System.Linq
 
                 try
                 {
-                    while (await enu.MoveNextAsync(cancellationToken).ConfigureAwait(false))
+                    while (await enu.MoveNextAsync().ConfigureAwait(false))
                     {
                         var item = enu.Current;
                         if (s.Add(_keySelector(item)))
@@ -224,7 +221,6 @@ namespace System.Linq
             {
                 Debug.Assert(source != null);
                 Debug.Assert(keySelector != null);
-                Debug.Assert(comparer != null);
 
                 _source = source;
                 _keySelector = keySelector;
@@ -291,12 +287,12 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
 
                         if (!await _enumerator.MoveNextAsync().ConfigureAwait(false))
                         {
@@ -307,9 +303,9 @@ namespace System.Linq
                         var element = _enumerator.Current;
                         _set = new Set<TKey>(_comparer);
                         _set.Add(await _keySelector(element).ConfigureAwait(false));
-                        current = element;
+                        _current = element;
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         return true;
 
                     case AsyncIteratorState.Iterating:
@@ -318,7 +314,7 @@ namespace System.Linq
                             element = _enumerator.Current;
                             if (_set.Add(await _keySelector(element).ConfigureAwait(false)))
                             {
-                                current = element;
+                                _current = element;
                                 return true;
                             }
                         }
@@ -339,7 +335,7 @@ namespace System.Linq
 
                 try
                 {
-                    while (await enu.MoveNextAsync(cancellationToken).ConfigureAwait(false))
+                    while (await enu.MoveNextAsync().ConfigureAwait(false))
                     {
                         var item = enu.Current;
                         if (s.Add(await _keySelector(item).ConfigureAwait(false)))

+ 32 - 37
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/DistinctUntilChanged.cs

@@ -14,17 +14,15 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> DistinctUntilChanged<TSource>(this IAsyncEnumerable<TSource> source)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
 
-            return DistinctUntilChangedCore(source, EqualityComparer<TSource>.Default);
+            return DistinctUntilChangedCore(source, comparer: null);
         }
 
         public static IAsyncEnumerable<TSource> DistinctUntilChanged<TSource>(this IAsyncEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(source));
 
             return DistinctUntilChangedCore(source, comparer);
         }
@@ -32,21 +30,19 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return DistinctUntilChangedCore(source, keySelector, EqualityComparer<TKey>.Default);
+            return DistinctUntilChangedCore(source, keySelector, comparer: null);
         }
 
         public static IAsyncEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(keySelector));
 
             return DistinctUntilChangedCore(source, keySelector, comparer);
         }
@@ -54,21 +50,21 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return DistinctUntilChangedCore(source, keySelector, EqualityComparer<TKey>.Default);
+            return DistinctUntilChangedCore<TSource, TKey>(source, keySelector, comparer: null);
         }
 
         public static IAsyncEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector, IEqualityComparer<TKey> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
             if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(comparer));
 
             return DistinctUntilChangedCore(source, keySelector, comparer);
         }
@@ -99,11 +95,10 @@ namespace System.Linq
 
             public DistinctUntilChangedAsyncIterator(IAsyncEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
             {
-                Debug.Assert(comparer != null);
                 Debug.Assert(source != null);
 
                 _source = source;
-                _comparer = comparer;
+                _comparer = comparer ?? EqualityComparer<TSource>.Default;
             }
 
             public override AsyncIterator<TSource> Clone()
@@ -123,13 +118,13 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -147,7 +142,7 @@ namespace System.Linq
                             {
                                 _hasCurrentValue = true;
                                 _currentValue = item;
-                                current = item;
+                                _current = item;
                                 return true;
                             }
                         }
@@ -174,7 +169,7 @@ namespace System.Linq
             {
                 _source = source;
                 _keySelector = keySelector;
-                _comparer = comparer;
+                _comparer = comparer ?? EqualityComparer<TKey>.Default;
             }
 
             public override AsyncIterator<TSource> Clone()
@@ -194,13 +189,13 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -218,7 +213,7 @@ namespace System.Linq
                             {
                                 _hasCurrentKey = true;
                                 _currentKeyValue = key;
-                                current = item;
+                                _current = item;
                                 return true;
                             }
                         }
@@ -245,7 +240,7 @@ namespace System.Linq
             {
                 _source = source;
                 _keySelector = keySelector;
-                _comparer = comparer;
+                _comparer = comparer ?? EqualityComparer<TKey>.Default;
             }
 
             public override AsyncIterator<TSource> Clone()
@@ -265,13 +260,13 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -289,7 +284,7 @@ namespace System.Linq
                             {
                                 _hasCurrentKey = true;
                                 _currentKeyValue = key;
-                                current = item;
+                                _current = item;
                                 return true;
                             }
                         }

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

@@ -14,9 +14,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Action<TSource> onNext)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (onNext == null)
-                throw new ArgumentNullException(nameof(onNext));
+                throw Error.ArgumentNull(nameof(onNext));
 
             return DoCore(source, onNext: onNext, onError: null, onCompleted: null);
         }
@@ -24,11 +24,11 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Action<TSource> onNext, Action onCompleted)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (onNext == null)
-                throw new ArgumentNullException(nameof(onNext));
+                throw Error.ArgumentNull(nameof(onNext));
             if (onCompleted == null)
-                throw new ArgumentNullException(nameof(onCompleted));
+                throw Error.ArgumentNull(nameof(onCompleted));
 
             return DoCore(source, onNext: onNext, onError: null, onCompleted: onCompleted);
         }
@@ -36,11 +36,11 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Action<TSource> onNext, Action<Exception> onError)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (onNext == null)
-                throw new ArgumentNullException(nameof(onNext));
+                throw Error.ArgumentNull(nameof(onNext));
             if (onError == null)
-                throw new ArgumentNullException(nameof(onError));
+                throw Error.ArgumentNull(nameof(onError));
 
             return DoCore(source, onNext: onNext, onError: onError, onCompleted: null);
         }
@@ -48,13 +48,13 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (onNext == null)
-                throw new ArgumentNullException(nameof(onNext));
+                throw Error.ArgumentNull(nameof(onNext));
             if (onError == null)
-                throw new ArgumentNullException(nameof(onError));
+                throw Error.ArgumentNull(nameof(onError));
             if (onCompleted == null)
-                throw new ArgumentNullException(nameof(onCompleted));
+                throw Error.ArgumentNull(nameof(onCompleted));
 
             return DoCore(source, onNext, onError, onCompleted);
         }
@@ -62,9 +62,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, Task> onNext)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (onNext == null)
-                throw new ArgumentNullException(nameof(onNext));
+                throw Error.ArgumentNull(nameof(onNext));
 
             return DoCore(source, onNext: onNext, onError: null, onCompleted: null);
         }
@@ -72,11 +72,11 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, Task> onNext, Func<Task> onCompleted)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (onNext == null)
-                throw new ArgumentNullException(nameof(onNext));
+                throw Error.ArgumentNull(nameof(onNext));
             if (onCompleted == null)
-                throw new ArgumentNullException(nameof(onCompleted));
+                throw Error.ArgumentNull(nameof(onCompleted));
 
             return DoCore(source, onNext: onNext, onError: null, onCompleted: onCompleted);
         }
@@ -84,11 +84,11 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, Task> onNext, Func<Exception, Task> onError)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (onNext == null)
-                throw new ArgumentNullException(nameof(onNext));
+                throw Error.ArgumentNull(nameof(onNext));
             if (onError == null)
-                throw new ArgumentNullException(nameof(onError));
+                throw Error.ArgumentNull(nameof(onError));
 
             return DoCore(source, onNext: onNext, onError: onError, onCompleted: null);
         }
@@ -96,13 +96,13 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, Task> onNext, Func<Exception, Task> onError, Func<Task> onCompleted)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (onNext == null)
-                throw new ArgumentNullException(nameof(onNext));
+                throw Error.ArgumentNull(nameof(onNext));
             if (onError == null)
-                throw new ArgumentNullException(nameof(onError));
+                throw Error.ArgumentNull(nameof(onError));
             if (onCompleted == null)
-                throw new ArgumentNullException(nameof(onCompleted));
+                throw Error.ArgumentNull(nameof(onCompleted));
 
             return DoCore(source, onNext, onError, onCompleted);
         }
@@ -110,9 +110,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Do<TSource>(this IAsyncEnumerable<TSource> source, IObserver<TSource> observer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (observer == null)
-                throw new ArgumentNullException(nameof(observer));
+                throw Error.ArgumentNull(nameof(observer));
 
             return DoCore(source, new Action<TSource>(observer.OnNext), new Action<Exception>(observer.OnError), new Action(observer.OnCompleted));
         }
@@ -163,13 +163,13 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -177,8 +177,8 @@ namespace System.Linq
                         {
                             if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                             {
-                                current = _enumerator.Current;
-                                _onNext(current);
+                                _current = _enumerator.Current;
+                                _onNext(_current);
 
                                 return true;
                             }
@@ -239,13 +239,13 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -253,8 +253,8 @@ namespace System.Linq
                         {
                             if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                             {
-                                current = _enumerator.Current;
-                                await _onNext(current).ConfigureAwait(false);
+                                _current = _enumerator.Current;
+                                await _onNext(_current).ConfigureAwait(false);
 
                                 return true;
                             }

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

@@ -14,9 +14,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Expand<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, IAsyncEnumerable<TSource>> selector)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (selector == null)
-                throw new ArgumentNullException(nameof(selector));
+                throw Error.ArgumentNull(nameof(selector));
 
             return new ExpandAsyncIterator<TSource>(source, selector);
         }
@@ -24,9 +24,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Expand<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<IAsyncEnumerable<TSource>>> selector)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (selector == null)
-                throw new ArgumentNullException(nameof(selector));
+                throw Error.ArgumentNull(nameof(selector));
 
             return new ExpandAsyncIteratorWithTask<TSource>(source, selector);
         }
@@ -67,15 +67,15 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
                         _queue = new Queue<IAsyncEnumerable<TSource>>();
                         _queue.Enqueue(_source);
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -92,7 +92,7 @@ namespace System.Linq
                                         await _enumerator.DisposeAsync().ConfigureAwait(false);
                                     }
 
-                                    _enumerator = src.GetAsyncEnumerator(cancellationToken);
+                                    _enumerator = src.GetAsyncEnumerator(_cancellationToken);
 
                                     continue; // loop
                                 }
@@ -105,7 +105,7 @@ namespace System.Linq
                                 var item = _enumerator.Current;
                                 var next = _selector(item);
                                 _queue.Enqueue(next);
-                                current = item;
+                                _current = item;
                                 return true;
                             }
 
@@ -157,15 +157,15 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
                         _queue = new Queue<IAsyncEnumerable<TSource>>();
                         _queue.Enqueue(_source);
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -182,7 +182,7 @@ namespace System.Linq
                                         await _enumerator.DisposeAsync().ConfigureAwait(false);
                                     }
 
-                                    _enumerator = src.GetAsyncEnumerator(cancellationToken);
+                                    _enumerator = src.GetAsyncEnumerator(_cancellationToken);
 
                                     continue; // loop
                                 }
@@ -195,7 +195,7 @@ namespace System.Linq
                                 var item = _enumerator.Current;
                                 var next = await _selector(item).ConfigureAwait(false);
                                 _queue.Enqueue(next);
-                                current = item;
+                                _current = item;
                                 return true;
                             }
 

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

@@ -14,9 +14,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Finally<TSource>(this IAsyncEnumerable<TSource> source, Action finallyAction)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (finallyAction == null)
-                throw new ArgumentNullException(nameof(finallyAction));
+                throw Error.ArgumentNull(nameof(finallyAction));
 
             return new FinallyAsyncIterator<TSource>(source, finallyAction);
         }
@@ -24,9 +24,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Finally<TSource>(this IAsyncEnumerable<TSource> source, Func<Task> finallyAction)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (finallyAction == null)
-                throw new ArgumentNullException(nameof(finallyAction));
+                throw Error.ArgumentNull(nameof(finallyAction));
 
             return new FinallyAsyncIteratorWithTask<TSource>(source, finallyAction);
         }
@@ -65,19 +65,19 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
                         if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                         {
-                            current = _enumerator.Current;
+                            _current = _enumerator.Current;
                             return true;
                         }
 
@@ -123,19 +123,19 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
                         if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                         {
-                            current = _enumerator.Current;
+                            _current = _enumerator.Current;
                             return true;
                         }
 

+ 7 - 15
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Generate.cs

@@ -14,19 +14,11 @@ namespace System.Linq
         public static IAsyncEnumerable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector)
         {
             if (condition == null)
-            {
-                throw new ArgumentNullException(nameof(condition));
-            }
-
+                throw Error.ArgumentNull(nameof(condition));
             if (iterate == null)
-            {
-                throw new ArgumentNullException(nameof(iterate));
-            }
-
+                throw Error.ArgumentNull(nameof(iterate));
             if (resultSelector == null)
-            {
-                throw new ArgumentNullException(nameof(resultSelector));
-            }
+                throw Error.ArgumentNull(nameof(resultSelector));
 
             return new GenerateAsyncIterator<TState, TResult>(initialState, condition, iterate, resultSelector);
         }
@@ -66,15 +58,15 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
                         _started = false;
                         _currentState = _initialState;
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -87,7 +79,7 @@ namespace System.Linq
 
                         if (_condition(_currentState))
                         {
-                            current = _resultSelector(_currentState);
+                            _current = _resultSelector(_currentState);
                             return true;
                         }
                         break;

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

@@ -14,9 +14,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> IgnoreElements<TSource>(this IAsyncEnumerable<TSource> source)
         {
             if (source == null)
-            {
-                throw new ArgumentNullException(nameof(source));
-            }
+                throw Error.ArgumentNull(nameof(source));
 
             return new IgnoreElementsAsyncIterator<TSource>(source);
         }
@@ -49,13 +47,13 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:

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

@@ -13,7 +13,7 @@ namespace System.Linq
         public static Task<bool> IsEmpty<TSource>(this IAsyncEnumerable<TSource> source)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
 
             return IsEmptyCore(source, CancellationToken.None);
         }
@@ -21,7 +21,7 @@ namespace System.Linq
         public static Task<bool> IsEmpty<TSource>(this IAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
 
             return IsEmptyCore(source, cancellationToken);
         }

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

@@ -13,9 +13,7 @@ namespace System.Linq
         public static Task<TSource> Max<TSource>(this IAsyncEnumerable<TSource> source, IComparer<TSource> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(source));
 
             return MaxCore(source, comparer, CancellationToken.None);
         }
@@ -23,25 +21,28 @@ namespace System.Linq
         public static Task<TSource> Max<TSource>(this IAsyncEnumerable<TSource> source, IComparer<TSource> comparer, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
-
+                throw Error.ArgumentNull(nameof(source));
+            
             return MaxCore(source, comparer, cancellationToken);
         }
 
         private static async Task<TSource> MaxCore<TSource>(IAsyncEnumerable<TSource> source, IComparer<TSource> comparer, CancellationToken cancellationToken)
         {
+            if (comparer == null)
+            {
+                comparer = Comparer<TSource>.Default;
+            }
+
             var e = source.GetAsyncEnumerator(cancellationToken);
 
             try
             {
-                if (!await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
-                    throw new InvalidOperationException(Strings.NO_ELEMENTS);
+                if (!await e.MoveNextAsync().ConfigureAwait(false))
+                    throw Error.NoElements();
 
                 var max = e.Current;
 
-                while (await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
+                while (await e.MoveNextAsync().ConfigureAwait(false))
                 {
                     var cur = e.Current;
 

+ 30 - 28
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxBy.cs

@@ -13,31 +13,29 @@ namespace System.Linq
         public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return MaxByCore(source, keySelector, Comparer<TKey>.Default, CancellationToken.None);
+            return MaxByCore(source, keySelector, comparer: null, CancellationToken.None);
         }
 
         public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return MaxByCore(source, keySelector, Comparer<TKey>.Default, cancellationToken);
+            return MaxByCore(source, keySelector, comparer: null, cancellationToken);
         }
 
         public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(keySelector));
 
             return MaxByCore(source, keySelector, comparer, CancellationToken.None);
         }
@@ -45,11 +43,9 @@ namespace System.Linq
         public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(keySelector));
 
             return MaxByCore(source, keySelector, comparer, cancellationToken);
         }
@@ -57,31 +53,29 @@ namespace System.Linq
         public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return MaxByCore(source, keySelector, Comparer<TKey>.Default, CancellationToken.None);
+            return MaxByCore<TSource, TKey>(source, keySelector, comparer: null, CancellationToken.None);
         }
 
         public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return MaxByCore(source, keySelector, Comparer<TKey>.Default, cancellationToken);
+            return MaxByCore<TSource, TKey>(source, keySelector, comparer: null, cancellationToken);
         }
 
         public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector, IComparer<TKey> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(keySelector));
 
             return MaxByCore(source, keySelector, comparer, CancellationToken.None);
         }
@@ -89,22 +83,30 @@ namespace System.Linq
         public static Task<IList<TSource>> MaxBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(keySelector));
 
             return MaxByCore(source, keySelector, comparer, cancellationToken);
         }
 
         private static Task<IList<TSource>> MaxByCore<TSource, TKey>(IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
+            if (comparer == null)
+            {
+                comparer = Comparer<TKey>.Default;
+            }
+
             return ExtremaBy(source, keySelector, (key, minValue) => comparer.Compare(key, minValue), cancellationToken);
         }
 
         private static Task<IList<TSource>> MaxByCore<TSource, TKey>(IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
+            if (comparer == null)
+            {
+                comparer = Comparer<TKey>.Default;
+            }
+
             return ExtremaBy(source, keySelector, (key, minValue) => comparer.Compare(key, minValue), cancellationToken);
         }
     }

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

@@ -14,7 +14,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Merge<TSource>(params IAsyncEnumerable<TSource>[] sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return new MergeAsyncIterator<TSource>(sources);
         }
@@ -22,7 +22,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Merge<TSource>(this IEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return sources.ToAsyncEnumerable().SelectMany(source => source);
         }
@@ -30,7 +30,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Merge<TSource>(this IAsyncEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return sources.SelectMany(source => source);
         }
@@ -76,9 +76,9 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
                         var n = _sources.Length;
@@ -89,12 +89,12 @@ namespace System.Linq
 
                         for (var i = 0; i < n; i++)
                         {
-                            var enumerator = _sources[i].GetAsyncEnumerator(cancellationToken);
+                            var enumerator = _sources[i].GetAsyncEnumerator(_cancellationToken);
                             _enumerators[i] = enumerator;
                             _moveNexts[i] = enumerator.MoveNextAsync();
                         }
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -118,7 +118,7 @@ namespace System.Linq
                             else
                             {
                                 var enumerator = _enumerators[index];
-                                current = enumerator.Current;
+                                _current = enumerator.Current;
                                 _moveNexts[index] = enumerator.MoveNextAsync();
                                 return true;
                             }

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

@@ -13,9 +13,7 @@ namespace System.Linq
         public static Task<TSource> Min<TSource>(this IAsyncEnumerable<TSource> source, IComparer<TSource> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(source));
 
             return MinCore(source, comparer, CancellationToken.None);
         }
@@ -23,25 +21,28 @@ namespace System.Linq
         public static Task<TSource> Min<TSource>(this IAsyncEnumerable<TSource> source, IComparer<TSource> comparer, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(source));
 
             return MinCore(source, comparer, cancellationToken);
         }
 
         private static async Task<TSource> MinCore<TSource>(IAsyncEnumerable<TSource> source, IComparer<TSource> comparer, CancellationToken cancellationToken)
         {
+            if (comparer == null)
+            {
+                comparer = Comparer<TSource>.Default;
+            }
+
             var e = source.GetAsyncEnumerator(cancellationToken);
 
             try
             {
-                if (!await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
-                    throw new InvalidOperationException(Strings.NO_ELEMENTS);
+                if (!await e.MoveNextAsync().ConfigureAwait(false))
+                    throw Error.NoElements();
 
                 var min = e.Current;
 
-                while (await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
+                while (await e.MoveNextAsync().ConfigureAwait(false))
                 {
                     var cur = e.Current;
 

+ 36 - 34
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinBy.cs

@@ -13,31 +13,29 @@ namespace System.Linq
         public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return MinByCore(source, keySelector, Comparer<TKey>.Default, CancellationToken.None);
+            return MinByCore(source, keySelector, comparer: null, CancellationToken.None);
         }
 
         public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return MinByCore(source, keySelector, Comparer<TKey>.Default, cancellationToken);
+            return MinByCore(source, keySelector, comparer: null, cancellationToken);
         }
 
         public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(keySelector));
 
             return MinByCore(source, keySelector, comparer, CancellationToken.None);
         }
@@ -45,11 +43,9 @@ namespace System.Linq
         public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(keySelector));
 
             return MinByCore(source, keySelector, comparer, cancellationToken);
         }
@@ -57,31 +53,29 @@ namespace System.Linq
         public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return MinByCore(source, keySelector, Comparer<TKey>.Default, CancellationToken.None);
+            return MinByCore<TSource, TKey>(source, keySelector, comparer: null, CancellationToken.None);
         }
 
         public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
+                throw Error.ArgumentNull(nameof(keySelector));
 
-            return MinByCore(source, keySelector, Comparer<TKey>.Default, cancellationToken);
+            return MinByCore<TSource, TKey>(source, keySelector, comparer: null, cancellationToken);
         }
 
         public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector, IComparer<TKey> comparer)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(keySelector));
 
             return MinByCore(source, keySelector, comparer, CancellationToken.None);
         }
@@ -89,22 +83,30 @@ namespace System.Linq
         public static Task<IList<TSource>> MinBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (keySelector == null)
-                throw new ArgumentNullException(nameof(keySelector));
-            if (comparer == null)
-                throw new ArgumentNullException(nameof(comparer));
+                throw Error.ArgumentNull(nameof(keySelector));
 
             return MinByCore(source, keySelector, comparer, cancellationToken);
         }
 
         private static Task<IList<TSource>> MinByCore<TSource, TKey>(IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
+            if (comparer == null)
+            {
+                comparer = Comparer<TKey>.Default;
+            }
+
             return ExtremaBy(source, keySelector, (key, minValue) => -comparer.Compare(key, minValue), cancellationToken);
         }
 
         private static Task<IList<TSource>> MinByCore<TSource, TKey>(IAsyncEnumerable<TSource> source, Func<TSource, Task<TKey>> keySelector, IComparer<TKey> comparer, CancellationToken cancellationToken)
         {
+            if (comparer == null)
+            {
+                comparer = Comparer<TKey>.Default;
+            }
+
             return ExtremaBy(source, keySelector, (key, minValue) => -comparer.Compare(key, minValue), cancellationToken);
         }
 
@@ -116,14 +118,14 @@ namespace System.Linq
 
             try
             {
-                if (!await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
-                    throw new InvalidOperationException(Strings.NO_ELEMENTS);
+                if (!await e.MoveNextAsync().ConfigureAwait(false))
+                    throw Error.NoElements();
 
                 var current = e.Current;
                 var resKey = keySelector(current);
                 result.Add(current);
 
-                while (await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
+                while (await e.MoveNextAsync().ConfigureAwait(false))
                 {
                     var cur = e.Current;
                     var key = keySelector(cur);
@@ -156,14 +158,14 @@ namespace System.Linq
 
             try
             {
-                if (!await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
-                    throw new InvalidOperationException(Strings.NO_ELEMENTS);
+                if (!await e.MoveNextAsync().ConfigureAwait(false))
+                    throw Error.NoElements();
 
                 var current = e.Current;
                 var resKey = await keySelector(current).ConfigureAwait(false);
                 result.Add(current);
 
-                while (await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
+                while (await e.MoveNextAsync().ConfigureAwait(false))
                 {
                     var cur = e.Current;
                     var key = await keySelector(cur).ConfigureAwait(false);

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

@@ -14,9 +14,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> OnErrorResumeNext<TSource>(this IAsyncEnumerable<TSource> first, IAsyncEnumerable<TSource> second)
         {
             if (first == null)
-                throw new ArgumentNullException(nameof(first));
+                throw Error.ArgumentNull(nameof(first));
             if (second == null)
-                throw new ArgumentNullException(nameof(second));
+                throw Error.ArgumentNull(nameof(second));
 
             return OnErrorResumeNextCore(new[] { first, second });
         }
@@ -24,7 +24,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> OnErrorResumeNext<TSource>(params IAsyncEnumerable<TSource>[] sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return OnErrorResumeNextCore(sources);
         }
@@ -32,7 +32,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> OnErrorResumeNext<TSource>(this IEnumerable<IAsyncEnumerable<TSource>> sources)
         {
             if (sources == null)
-                throw new ArgumentNullException(nameof(sources));
+                throw Error.ArgumentNull(nameof(sources));
 
             return OnErrorResumeNextCore(sources);
         }
@@ -78,14 +78,14 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
                         _sourcesEnumerator = _sources.GetEnumerator();
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -98,14 +98,14 @@ namespace System.Linq
                                     break; // while -- done, nothing else to do
                                 }
 
-                                _enumerator = _sourcesEnumerator.Current.GetAsyncEnumerator(cancellationToken);
+                                _enumerator = _sourcesEnumerator.Current.GetAsyncEnumerator(_cancellationToken);
                             }
 
                             try
                             {
                                 if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                                 {
-                                    current = _enumerator.Current;
+                                    _current = _enumerator.Current;
                                     return true;
                                 }
                             }

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

@@ -19,7 +19,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Repeat<TSource>(this IAsyncEnumerable<TSource> source)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
 
             return new RepeatSequenceAsyncIterator<TSource>(source, -1);
         }
@@ -27,9 +27,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Repeat<TSource>(this IAsyncEnumerable<TSource> source, int count)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (count < 0)
-                throw new ArgumentOutOfRangeException(nameof(count));
+                throw Error.ArgumentOutOfRange(nameof(count));
 
             return new RepeatSequenceAsyncIterator<TSource>(source, count);
         }
@@ -48,12 +48,12 @@ namespace System.Linq
                 return new RepeatElementAsyncIterator<TResult>(_element);
             }
 
-            protected override ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override ValueTask<bool> MoveNextCore()
             {
-                cancellationToken.ThrowIfCancellationRequested();
+                _cancellationToken.ThrowIfCancellationRequested();
 
-                current = _element;
-                return TaskExt.True;
+                _current = _element;
+                return new ValueTask<bool>(true);
             }
         }
 
@@ -92,9 +92,9 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
 
@@ -107,15 +107,15 @@ namespace System.Linq
                         if (!_isInfinite && _currentCount-- == 0)
                             break;
 
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
 
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
                         if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                         {
-                            current = _enumerator.Current;
+                            _current = _enumerator.Current;
                             return true;
                         }
 

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

@@ -11,7 +11,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Retry<TSource>(this IAsyncEnumerable<TSource> source)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
 
             return new[] { source }.Repeat().Catch();
         }
@@ -19,9 +19,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Retry<TSource>(this IAsyncEnumerable<TSource> source, int retryCount)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (retryCount < 0)
-                throw new ArgumentOutOfRangeException(nameof(retryCount));
+                throw Error.ArgumentOutOfRange(nameof(retryCount));
 
             return new[] { source }.Repeat(retryCount).Catch();
         }

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

@@ -14,9 +14,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Scan<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, TSource, TSource> accumulator)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (accumulator == null)
-                throw new ArgumentNullException(nameof(accumulator));
+                throw Error.ArgumentNull(nameof(accumulator));
 
             return new ScanAsyncEnumerable<TSource>(source, accumulator);
         }
@@ -24,9 +24,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TAccumulate> Scan<TSource, TAccumulate>(this IAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (accumulator == null)
-                throw new ArgumentNullException(nameof(accumulator));
+                throw Error.ArgumentNull(nameof(accumulator));
 
             return new ScanAsyncEnumerable<TSource, TAccumulate>(source, seed, accumulator);
         }
@@ -34,9 +34,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Scan<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, TSource, Task<TSource>> accumulator)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (accumulator == null)
-                throw new ArgumentNullException(nameof(accumulator));
+                throw Error.ArgumentNull(nameof(accumulator));
 
             return new ScanAsyncEnumerableWithTask<TSource>(source, accumulator);
         }
@@ -44,9 +44,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TAccumulate> Scan<TSource, TAccumulate>(this IAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, Task<TAccumulate>> accumulator)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (accumulator == null)
-                throw new ArgumentNullException(nameof(accumulator));
+                throw Error.ArgumentNull(nameof(accumulator));
 
             return new ScanAsyncEnumerableWithTask<TSource, TAccumulate>(source, seed, accumulator);
         }
@@ -87,16 +87,16 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
                         _hasSeed = false;
                         _accumulated = default;
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -112,7 +112,7 @@ namespace System.Linq
                             }
 
                             _accumulated = _accumulator(_accumulated, item);
-                            current = _accumulated;
+                            _current = _accumulated;
                             return true;
                         }
 
@@ -161,15 +161,15 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
                         _accumulated = _seed;
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -177,7 +177,7 @@ namespace System.Linq
                         {
                             var item = _enumerator.Current;
                             _accumulated = _accumulator(_accumulated, item);
-                            current = _accumulated;
+                            _current = _accumulated;
                             return true;
                         }
 
@@ -225,16 +225,16 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
                         _hasSeed = false;
                         _accumulated = default;
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -250,7 +250,7 @@ namespace System.Linq
                             }
 
                             _accumulated = await _accumulator(_accumulated, item).ConfigureAwait(false);
-                            current = _accumulated;
+                            _current = _accumulated;
                             return true;
                         }
 
@@ -299,15 +299,15 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
                         _accumulated = _seed;
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -315,7 +315,7 @@ namespace System.Linq
                         {
                             var item = _enumerator.Current;
                             _accumulated = await _accumulator(_accumulated, item).ConfigureAwait(false);
-                            current = _accumulated;
+                            _current = _accumulated;
                             return true;
                         }
 

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

@@ -11,9 +11,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TOther> SelectMany<TSource, TOther>(this IAsyncEnumerable<TSource> source, IAsyncEnumerable<TOther> other)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
             if (other == null)
-                throw new ArgumentNullException(nameof(other));
+                throw Error.ArgumentNull(nameof(other));
 
             return source.SelectMany(_ => other);
         }

+ 1 - 3
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/StartWith.cs

@@ -11,9 +11,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> StartWith<TSource>(this IAsyncEnumerable<TSource> source, params TSource[] values)
         {
             if (source == null)
-            {
-                throw new ArgumentNullException(nameof(source));
-            }
+                throw Error.ArgumentNull(nameof(source));
 
             return values.ToAsyncEnumerable().Concat(source);
         }

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

@@ -13,7 +13,7 @@ namespace System.Linq
         public static IAsyncEnumerable<TValue> Throw<TValue>(Exception exception)
         {
             if (exception == null)
-                throw new ArgumentNullException(nameof(exception));
+                throw Error.ArgumentNull(nameof(exception));
 
 #if NO_TASK_FROMEXCEPTION
             var tcs = new TaskCompletionSource<bool>();

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

@@ -14,11 +14,11 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Timeout<TSource>(this IAsyncEnumerable<TSource> source, TimeSpan timeout)
         {
             if (source == null)
-                throw new ArgumentNullException(nameof(source));
+                throw Error.ArgumentNull(nameof(source));
 
             var num = (long)timeout.TotalMilliseconds;
             if (num < -1L || num > int.MaxValue)
-                throw new ArgumentOutOfRangeException(nameof(timeout));
+                throw Error.ArgumentOutOfRange(nameof(timeout));
 
             return new TimeoutAsyncIterator<TSource>(source, timeout);
         }
@@ -62,14 +62,14 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _source.GetAsyncEnumerator(cancellationToken);
+                        _enumerator = _source.GetAsyncEnumerator(_cancellationToken);
 
-                        state = AsyncIteratorState.Iterating;
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
@@ -99,7 +99,7 @@ namespace System.Linq
 
                         if (await moveNext.ConfigureAwait(false))
                         {
-                            current = _enumerator.Current;
+                            _current = _enumerator.Current;
                             return true;
                         }
 

+ 19 - 25
Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Using.cs

@@ -14,9 +14,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IAsyncEnumerable<TSource>> enumerableFactory) where TResource : IDisposable
         {
             if (resourceFactory == null)
-                throw new ArgumentNullException(nameof(resourceFactory));
+                throw Error.ArgumentNull(nameof(resourceFactory));
             if (enumerableFactory == null)
-                throw new ArgumentNullException(nameof(enumerableFactory));
+                throw Error.ArgumentNull(nameof(enumerableFactory));
 
             return new UsingAsyncIterator<TSource, TResource>(resourceFactory, enumerableFactory);
         }
@@ -24,9 +24,9 @@ namespace System.Linq
         public static IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<Task<TResource>> resourceFactory, Func<TResource, Task<IAsyncEnumerable<TSource>>> enumerableFactory) where TResource : IDisposable
         {
             if (resourceFactory == null)
-                throw new ArgumentNullException(nameof(resourceFactory));
+                throw Error.ArgumentNull(nameof(resourceFactory));
             if (enumerableFactory == null)
-                throw new ArgumentNullException(nameof(enumerableFactory));
+                throw Error.ArgumentNull(nameof(enumerableFactory));
 
             return new UsingAsyncIteratorWithTask<TSource, TResource>(resourceFactory, enumerableFactory);
         }
@@ -36,7 +36,6 @@ namespace System.Linq
             private readonly Func<TResource, IAsyncEnumerable<TSource>> _enumerableFactory;
             private readonly Func<TResource> _resourceFactory;
 
-            private IAsyncEnumerable<TSource> _enumerable;
             private IAsyncEnumerator<TSource> _enumerator;
             private TResource _resource;
 
@@ -71,19 +70,24 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                // NB: Earlier behavior of this operator was more eager, causing the resource factory to be called upon calling
+                //     GetAsyncEnumerator. This is inconsistent with asynchronous "using" and with a C# 8.0 async iterator with
+                //     a using statement inside, so this logic got moved to MoveNextAsync instead.
+
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
-                        _enumerator = _enumerable.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _resource = _resourceFactory();
+                        _enumerator = _enumerableFactory(_resource).GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
                         while (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                         {
-                            current = _enumerator.Current;
+                            _current = _enumerator.Current;
                             return true;
                         }
 
@@ -93,16 +97,6 @@ namespace System.Linq
 
                 return false;
             }
-
-            protected override void OnGetEnumerator(CancellationToken cancellationToken)
-            {
-                // REVIEW: Wire cancellation to the functions.
-
-                _resource = _resourceFactory();
-                _enumerable = _enumerableFactory(_resource);
-
-                base.OnGetEnumerator(cancellationToken);
-            }
         }
 
         private sealed class UsingAsyncIteratorWithTask<TSource, TResource> : AsyncIterator<TSource> where TResource : IDisposable
@@ -145,22 +139,22 @@ namespace System.Linq
                 await base.DisposeAsync().ConfigureAwait(false);
             }
 
-            protected override async ValueTask<bool> MoveNextCore(CancellationToken cancellationToken)
+            protected override async ValueTask<bool> MoveNextCore()
             {
-                switch (state)
+                switch (_state)
                 {
                     case AsyncIteratorState.Allocated:
                         _resource = await _resourceFactory().ConfigureAwait(false);
                         _enumerable = await _enumerableFactory(_resource).ConfigureAwait(false);
 
-                        _enumerator = _enumerable.GetAsyncEnumerator(cancellationToken);
-                        state = AsyncIteratorState.Iterating;
+                        _enumerator = _enumerable.GetAsyncEnumerator(_cancellationToken);
+                        _state = AsyncIteratorState.Iterating;
                         goto case AsyncIteratorState.Iterating;
 
                     case AsyncIteratorState.Iterating:
                         while (await _enumerator.MoveNextAsync().ConfigureAwait(false))
                         {
-                            current = _enumerator.Current;
+                            _current = _enumerator.Current;
                             return true;
                         }
 

+ 0 - 86
Ix.NET/Source/System.Interactive.Async/System/Linq/Set.cs

@@ -1,86 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the Apache 2.0 License.
-// See the LICENSE file in the project root for more information. 
-
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-
-// from https://github.com/dotnet/corefx/blob/ec2685715b01d12f16b08d0dfa326649b12db8ec/src/System.Linq/src/System/Linq/Set.cs
-namespace System.Linq
-{
-    [ExcludeFromCodeCoverage]
-    internal sealed class Set<TElement>
-    {
-        private readonly IEqualityComparer<TElement> _comparer;
-        private int[] _buckets;
-
-        private Slot[] _slots;
-
-        public Set(IEqualityComparer<TElement> comparer)
-        {
-            _comparer = comparer ?? EqualityComparer<TElement>.Default;
-            _buckets = new int[7];
-            _slots = new Slot[7];
-        }
-
-        internal int Count { get; private set; }
-
-        // If value is not in set, add it and return true; otherwise return false
-        public bool Add(TElement value)
-        {
-            var hashCode = InternalGetHashCode(value);
-            for (var i = _buckets[hashCode%_buckets.Length] - 1; i >= 0; i = _slots[i]._next)
-            {
-                if (_slots[i]._hashCode == hashCode && _comparer.Equals(_slots[i]._value, value))
-                {
-                    return false;
-                }
-            }
-
-            if (Count == _slots.Length)
-            {
-                Resize();
-            }
-
-            var index = Count;
-            Count++;
-            var bucket = hashCode%_buckets.Length;
-            _slots[index]._hashCode = hashCode;
-            _slots[index]._value = value;
-            _slots[index]._next = _buckets[bucket] - 1;
-            _buckets[bucket] = index + 1;
-            return true;
-        }
-
-        internal int InternalGetHashCode(TElement value)
-        {
-            // Handle comparer implementations that throw when passed null
-            return (value == null) ? 0 : _comparer.GetHashCode(value) & 0x7FFFFFFF;
-        }
-
-        private void Resize()
-        {
-            var newSize = checked((Count*2) + 1);
-            var newBuckets = new int[newSize];
-            var newSlots = new Slot[newSize];
-            Array.Copy(_slots, 0, newSlots, 0, Count);
-            for (var i = 0; i < Count; i++)
-            {
-                var bucket = newSlots[i]._hashCode%newSize;
-                newSlots[i]._next = newBuckets[bucket] - 1;
-                newBuckets[bucket] = i + 1;
-            }
-
-            _buckets = newBuckets;
-            _slots = newSlots;
-        }
-
-        internal struct Slot
-        {
-            internal int _hashCode;
-            internal int _next;
-            internal TElement _value;
-        }
-    }
-}

+ 0 - 13
Ix.NET/Source/System.Interactive.Async/System/Linq/Strings.cs

@@ -1,13 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the Apache 2.0 License.
-// See the LICENSE file in the project root for more information. 
-
-namespace System.Linq
-{
-    internal static class Strings
-    {
-        public static string NO_ELEMENTS = "Source sequence doesn't contain any elements.";
-        public static string MORE_THAN_ONE_ELEMENT = "Source sequence contains more than one element.";
-        public static string NOT_SUPPORTED = "Specified method is not supported.";
-    }
-}

+ 0 - 3
Ix.NET/Source/System.Interactive.Async/TaskExt.cs

@@ -6,9 +6,6 @@ namespace System.Threading.Tasks
 {
     internal static class TaskExt
     {
-        public static readonly ValueTask<bool> True = new ValueTask<bool>(true);
-        public static readonly ValueTask<bool> False = new ValueTask<bool>(false);
-        public static readonly ValueTask CompletedTask = new ValueTask(Task.FromResult(true));
         public static readonly ValueTask<bool> Never = new ValueTask<bool>(new TaskCompletionSource<bool>().Task);
     }
 }

+ 4 - 0
Ix.NET/Source/System.Linq.Async.Queryable/System.Linq.Async.Queryable.csproj

@@ -23,4 +23,8 @@
     </None>
   </ItemGroup>
 
+  <ItemGroup>
+    <Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
+  </ItemGroup>
+
 </Project>

+ 5 - 35
Ix.NET/Source/System.Linq.Async.Queryable/System/Linq/AsyncEnumerableQuery.cs

@@ -56,57 +56,27 @@ namespace System.Linq
         /// <summary>
         /// Gets the type of the elements in the sequence.
         /// </summary>
-        Type IAsyncQueryable.ElementType
-        {
-            get
-            {
-                return typeof(T);
-            }
-        }
+        Type IAsyncQueryable.ElementType => typeof(T);
 
         /// <summary>
         /// Gets the expression representing the sequence.
         /// </summary>
-        Expression IAsyncQueryable.Expression
-        {
-            get
-            {
-                return _expression;
-            }
-        }
+        Expression IAsyncQueryable.Expression => _expression;
 
         /// <summary>
         /// Gets the query provider used to execute the sequence.
         /// </summary>
-        IAsyncQueryProvider IAsyncQueryable.Provider
-        {
-            get
-            {
-                return this;
-            }
-        }
+        IAsyncQueryProvider IAsyncQueryable.Provider => this;
 
         /// <summary>
         /// Gets the enumerable sequence obtained from evaluating the expression tree.
         /// </summary>
-        internal override object Enumerable
-        {
-            get
-            {
-                return _enumerable;
-            }
-        }
+        internal override object Enumerable => _enumerable;
 
         /// <summary>
         /// Gets the expression tree representing the asynchronous enumerable sequence.
         /// </summary>
-        internal override Expression Expression
-        {
-            get
-            {
-                return _expression;
-            }
-        }
+        internal override Expression Expression => _expression;
 
         /// <summary>
         /// Creates a new asynchronous enumerable sequence represented by an expression tree.

+ 0 - 1
Ix.NET/Source/System.Linq.Async.Queryable/System/Linq/AsyncEnumerableRewriter.cs

@@ -19,7 +19,6 @@ namespace System.Linq
 
         protected override Expression VisitConstant(ConstantExpression node)
         {
-
             //
             // Not an expression representation obtained from the async enumerable query provider,
             // so just a plain constant that can be returned as-is.

File diff suppressed because it is too large
+ 172 - 172
Ix.NET/Source/System.Linq.Async.Queryable/System/Linq/AsyncQueryable.Generated.cs


+ 1 - 1
Ix.NET/Source/System.Linq.Async.Queryable/System/Linq/AsyncQueryable.Generated.tt

@@ -129,7 +129,7 @@ foreach (var m in typeof(AsyncEnumerable).GetMethods()
                         .OrderBy(m => m.Name)
                         .ThenBy(m => m.IsGenericMethod ? m.GetGenericArguments().Length : 0)
                         .ThenBy(m => m.GetParameters().Length)
-                        .ThenBy(m => string.Join(", ", m.GetParameters().Select(p => p.Name))))
+                        .ThenBy(m => string.Join(", ", m.GetParameters().Select((p, i) => toQuoted(p.ParameterType, i) + " " + p.Name))))
 {
     var genArgs = m.GetGenericArguments();
 

+ 40 - 34
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/AsyncEnumerableTests.cs

@@ -14,50 +14,42 @@ namespace Tests
     public class AsyncEnumerableTests
     {
         protected static readonly IAsyncEnumerable<int> Return42 = new[] { 42 }.ToAsyncEnumerable();
-        protected static Func<Exception, bool> SingleInnerExceptionMatches(Exception ex) => e => ((AggregateException)e).Flatten().InnerExceptions.Single() == ex;
 
-        protected const int WaitTimeoutMs = 5000;
-
-#pragma warning disable xUnit1013 // Public method should be marked as test
-        public void AssertThrows<E>(Action a)
-            where E : Exception
+        protected async Task AssertThrowsAsync<TException>(Task t)
+            where TException : Exception
         {
-            Assert.Throws<E>(a);
+            await Assert.ThrowsAsync<TException>(() => t);
         }
 
-        public void AssertThrows<E>(Action a, Func<E, bool> assert)
-            where E : Exception
+        protected async Task AssertThrowsAsync(Task t, Exception e)
         {
-            var hasFailed = false;
-
             try
             {
-                a();
+                await t;
             }
-            catch (E e)
+            catch (Exception ex)
             {
-                Assert.True(assert(e));
-                hasFailed = true;
+                Assert.Same(e, ex);
             }
+        }
 
-            if (!hasFailed)
-            {
-                Assert.True(false);
-            }
+        protected Task AssertThrowsAsync<T>(ValueTask<T> t, Exception e)
+        {
+            return AssertThrowsAsync(t.AsTask(), e);
         }
 
-        public void NoNext<T>(IAsyncEnumerator<T> e)
+        protected async Task NoNextAsync<T>(IAsyncEnumerator<T> e)
         {
-            Assert.False(e.MoveNextAsync().Result);
+            Assert.False(await e.MoveNextAsync());
         }
 
-        public void HasNext<T>(IAsyncEnumerator<T> e, T value)
+        protected async Task HasNextAsync<T>(IAsyncEnumerator<T> e, T value)
         {
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.Equal(value, e.Current);
         }
 
-        public async Task SequenceIdentity<T>(IAsyncEnumerable<T> enumerable)
+        protected async Task SequenceIdentity<T>(IAsyncEnumerable<T> enumerable)
         {
             var en1 = enumerable.GetAsyncEnumerator();
             var en2 = enumerable.GetAsyncEnumerator();
@@ -67,18 +59,11 @@ namespace Tests
             await en1.DisposeAsync();
             await en2.DisposeAsync();
 
-            var e1t = enumerable.ToList();
-            var e2t = enumerable.ToList();
+            var res1 = await enumerable.ToList();
+            var res2 = await enumerable.ToList();
 
-            await Task.WhenAll(e1t, e2t);
-
-
-            var e1Result = e1t.Result;
-            var e2Result = e2t.Result;
-
-            e1Result.ShouldAllBeEquivalentTo(e2Result);
+            res1.ShouldAllBeEquivalentTo(res2);
         }
-#pragma warning restore xUnit1013 // Public method should be marked as test
 
         protected static IAsyncEnumerable<TValue> Throw<TValue>(Exception exception)
         {
@@ -100,5 +85,26 @@ namespace Tests
                     dispose: null)
             );
         }
+
+        private void AssertThrows<E>(Action a, Func<E, bool> assert)
+            where E : Exception
+        {
+            var hasFailed = false;
+
+            try
+            {
+                a();
+            }
+            catch (E e)
+            {
+                Assert.True(assert(e));
+                hasFailed = true;
+            }
+
+            if (!hasFailed)
+            {
+                Assert.True(false);
+            }
+        }
     }
 }

+ 32 - 33
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Aggregate.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -17,135 +16,135 @@ namespace Tests
         public async Task Aggregate_Null()
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int>(default, (x, y) => x + y));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int>(Return42, default(Func<int, int, int>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate(Return42, default(Func<int, int, int>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int, int>(default, 0, (x, y) => x + y));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int, int>(Return42, 0, default(Func<int, int, int>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate(Return42, 0, default(Func<int, int, int>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int, int, int>(default, 0, (x, y) => x + y, z => z));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int, int, int>(Return42, 0, default, z => z));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate(Return42, 0, default, z => z));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int, int, int>(Return42, 0, (x, y) => x + y, default));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int>(default, (x, y) => x + y, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int>(Return42, default(Func<int, int, int>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate(Return42, default(Func<int, int, int>), CancellationToken.None));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int, int>(default, 0, (x, y) => x + y, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int, int>(Return42, 0, default(Func<int, int, int>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate(Return42, 0, default(Func<int, int, int>), CancellationToken.None));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int, int, int>(default, 0, (x, y) => x + y, z => z, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int, int, int>(Return42, 0, default, z => z, CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate(Return42, 0, default, z => z, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Aggregate<int, int, int>(Return42, 0, (x, y) => x + y, default, CancellationToken.None));
         }
 
         [Fact]
-        public void Aggregate1()
+        public async Task Aggregate1Async()
         {
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
             var ys = xs.Aggregate((x, y) => x * y);
-            Assert.Equal(24, ys.Result);
+            Assert.Equal(24, await ys);
         }
 
         [Fact]
-        public void Aggregate2()
+        public async Task Aggregate2Async()
         {
             var xs = new int[0].ToAsyncEnumerable();
             var ys = xs.Aggregate((x, y) => x * y);
-            AssertThrows<Exception>(() => ys.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await AssertThrowsAsync<InvalidOperationException>(ys);
         }
 
         [Fact]
-        public void Aggregate3()
+        public async Task Aggregate3Async()
         {
             var ex = new Exception("Bang!");
             var xs = Throw<int>(ex);
             var ys = xs.Aggregate((x, y) => x * y);
-            AssertThrows<Exception>(() => ys.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(ys, ex);
         }
 
         [Fact]
-        public void Aggregate4()
+        public async Task Aggregate4Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
             var ys = xs.Aggregate(new Func<int, int, int>((x, y) => { throw ex; }));
-            AssertThrows<Exception>(() => ys.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(ys, ex);
         }
 
         [Fact]
-        public void Aggregate5()
+        public async Task Aggregate5Async()
         {
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
             var ys = xs.Aggregate(1, (x, y) => x * y);
-            Assert.Equal(24, ys.Result);
+            Assert.Equal(24, await ys);
         }
 
         [Fact]
-        public void Aggregate6()
+        public async Task Aggregate6Async()
         {
             var xs = new int[0].ToAsyncEnumerable();
             var ys = xs.Aggregate(1, (x, y) => x * y);
-            Assert.Equal(1, ys.Result);
+            Assert.Equal(1, await ys);
         }
 
         [Fact]
-        public void Aggregate7()
+        public async Task Aggregate7Async()
         {
             var ex = new Exception("Bang!");
             var xs = Throw<int>(ex);
             var ys = xs.Aggregate(1, (x, y) => x * y);
-            AssertThrows<Exception>(() => ys.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(ys, ex);
         }
 
         [Fact]
-        public void Aggregate8()
+        public async Task Aggregate8Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
             var ys = xs.Aggregate(1, new Func<int, int, int>((x, y) => { throw ex; }));
-            AssertThrows<Exception>(() => ys.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(ys, ex);
         }
 
         [Fact]
-        public void Aggregate9()
+        public async Task Aggregate9Async()
         {
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
             var ys = xs.Aggregate(1, (x, y) => x * y, x => x + 1);
-            Assert.Equal(25, ys.Result);
+            Assert.Equal(25, await ys);
         }
 
         [Fact]
-        public void Aggregate10()
+        public async Task Aggregate10Async()
         {
             var xs = new int[0].ToAsyncEnumerable();
             var ys = xs.Aggregate(1, (x, y) => x * y, x => x + 1);
-            Assert.Equal(2, ys.Result);
+            Assert.Equal(2, await ys);
         }
 
         [Fact]
-        public void Aggregate11()
+        public async Task Aggregate11Async()
         {
             var ex = new Exception("Bang!");
             var xs = Throw<int>(ex);
             var ys = xs.Aggregate(1, (x, y) => x * y, x => x + 1);
-            AssertThrows<Exception>(() => ys.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(ys, ex);
         }
 
         [Fact]
-        public void Aggregate12()
+        public async Task Aggregate12Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
             var ys = xs.Aggregate(1, (x, y) => { throw ex; }, x => x + 1);
-            AssertThrows<Exception>(() => ys.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(ys, ex);
         }
 
         [Fact]
-        public void Aggregate13()
+        public async Task Aggregate13Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
             var ys = xs.Aggregate<int, int, int>(1, (x, y) => x * y, x => { throw ex; });
-            AssertThrows<Exception>(() => ys.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(ys, ex);
         }
     }
 }

+ 10 - 11
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/All.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -17,40 +16,40 @@ namespace Tests
         public async Task All_Null()
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.All<int>(default, x => true));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.All<int>(Return42, default(Func<int, bool>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.All(Return42, default(Func<int, bool>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.All<int>(default, x => true, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.All<int>(Return42, default(Func<int, bool>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.All(Return42, default(Func<int, bool>), CancellationToken.None));
         }
 
         [Fact]
-        public void All1()
+        public async Task All1Async()
         {
             var res = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable().All(x => x % 2 == 0);
-            Assert.False(res.Result);
+            Assert.False(await res);
         }
 
         [Fact]
-        public void All2()
+        public async Task All2Async()
         {
             var res = new[] { 2, 8, 4 }.ToAsyncEnumerable().All(x => x % 2 == 0);
-            Assert.True(res.Result);
+            Assert.True(await res);
         }
 
         [Fact]
-        public void All3()
+        public async Task All3Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).All(x => x % 2 == 0);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void All4()
+        public async Task All4Async()
         {
             var ex = new Exception("Bang!");
             var res = new[] { 2, 8, 4 }.ToAsyncEnumerable().All(new Func<int, bool>(x => { throw ex; }));
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
     }
 }

+ 14 - 15
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Any.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -18,55 +17,55 @@ namespace Tests
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Any<int>(default));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Any<int>(default, x => true));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Any<int>(Return42, default(Func<int, bool>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Any(Return42, default(Func<int, bool>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Any<int>(default, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Any<int>(default, x => true, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Any<int>(Return42, default(Func<int, bool>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Any(Return42, default(Func<int, bool>), CancellationToken.None));
         }
 
         [Fact]
-        public void Any1()
+        public async Task Any1Async()
         {
             var res = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable().Any(x => x % 2 == 0);
-            Assert.True(res.Result);
+            Assert.True(await res);
         }
 
         [Fact]
-        public void Any2()
+        public async Task Any2Async()
         {
             var res = new[] { 2, 8, 4 }.ToAsyncEnumerable().Any(x => x % 2 != 0);
-            Assert.False(res.Result);
+            Assert.False(await res);
         }
 
         [Fact]
-        public void Any3()
+        public async Task Any3Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).Any(x => x % 2 == 0);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void Any4()
+        public async Task Any4Async()
         {
             var ex = new Exception("Bang!");
             var res = new[] { 2, 8, 4 }.ToAsyncEnumerable().Any(new Func<int, bool>(x => { throw ex; }));
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void Any5()
+        public async Task Any5Async()
         {
             var res = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable().Any();
-            Assert.True(res.Result);
+            Assert.True(await res);
         }
 
         [Fact]
-        public void Any6()
+        public async Task Any6Async()
         {
             var res = new int[0].ToAsyncEnumerable().Any();
-            Assert.False(res.Result);
+            Assert.False(await res);
         }
     }
 }

+ 15 - 15
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Append.cs

@@ -15,11 +15,11 @@ namespace Tests
         [Fact]
         public void Append_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Append(default, 42));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Append(default, 42));
         }
 
         [Fact]
-        public void Append1()
+        public async Task Append1()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
 
@@ -27,11 +27,11 @@ namespace Tests
 
             var e = res.GetAsyncEnumerator();
 
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await NoNextAsync(e);
         }
 
         [Fact]
@@ -108,7 +108,7 @@ namespace Tests
 
 
         [Fact]
-        public void AppendN1()
+        public async Task AppendN1()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
 
@@ -118,13 +118,13 @@ namespace Tests
 
             var e = res.GetAsyncEnumerator();
 
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await NoNextAsync(e);
         }
 
         [Fact]

+ 1 - 13
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/AsAsyncEnumerable.cs

@@ -2,8 +2,6 @@
 // The .NET Foundation licenses this file to you under the Apache 2.0 License.
 // See the LICENSE file in the project root for more information. 
 
-using System;
-using System.Collections.Generic;
 using System.Linq;
 using Xunit;
 
@@ -11,23 +9,13 @@ namespace Tests
 {
     public class AsAsyncEnumerable : AsyncEnumerableTests
     {
-        [Fact]
-        public void AsAsyncEnumerable_Null()
-        {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.AsAsyncEnumerable(default(IAsyncEnumerable<int>)));
-        }
-
         [Fact]
         public void AsAsyncEnumerable1()
         {
             var xs = Return42;
             var ys = xs.AsAsyncEnumerable();
 
-            Assert.NotSame(xs, ys);
-
-            var e = xs.GetAsyncEnumerator();
-            HasNext(e, 42);
-            NoNext(e);
+            Assert.Same(xs, ys); // NB: Consistent with LINQ to Objects behavior.
         }
     }
 }

+ 50 - 50
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Average.cs

@@ -84,173 +84,173 @@ namespace Tests
         }
 
         [Fact]
-        public void Average1()
+        public async Task Average1()
         {
             var xs = new[] { 1, 2, 3 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Average(), ys.Average().Result);
-            Assert.Equal(xs.Average(), ys.Average(x => x).Result);
+            Assert.Equal(xs.Average(), await ys.Average());
+            Assert.Equal(xs.Average(), await ys.Average(x => x));
         }
 
         [Fact]
-        public void Average2()
+        public async Task Average2()
         {
             var xs = new[] { 1, default(int?), 3 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Average(), ys.Average().Result);
-            Assert.Equal(xs.Average(), ys.Average(x => x).Result);
+            Assert.Equal(xs.Average(), await ys.Average());
+            Assert.Equal(xs.Average(), await ys.Average(x => x));
         }
 
         [Fact]
-        public void Average3()
+        public async Task Average3()
         {
             var xs = new[] { 1L, 2L, 3L };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Average(), ys.Average().Result);
-            Assert.Equal(xs.Average(), ys.Average(x => x).Result);
+            Assert.Equal(xs.Average(), await ys.Average());
+            Assert.Equal(xs.Average(), await ys.Average(x => x));
         }
 
         [Fact]
-        public void Average4()
+        public async Task Average4()
         {
             var xs = new[] { 1L, default(long?), 3L };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Average(), ys.Average().Result);
-            Assert.Equal(xs.Average(), ys.Average(x => x).Result);
+            Assert.Equal(xs.Average(), await ys.Average());
+            Assert.Equal(xs.Average(), await ys.Average(x => x));
         }
 
         [Fact]
-        public void Average5()
+        public async Task Average5()
         {
             var xs = new[] { 1.0, 2.0, 3.0 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Average(), ys.Average().Result);
-            Assert.Equal(xs.Average(), ys.Average(x => x).Result);
+            Assert.Equal(xs.Average(), await ys.Average());
+            Assert.Equal(xs.Average(), await ys.Average(x => x));
         }
 
         [Fact]
-        public void Average6()
+        public async Task Average6()
         {
             var xs = new[] { 1.0, default(double?), 3.0 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Average(), ys.Average().Result);
-            Assert.Equal(xs.Average(), ys.Average(x => x).Result);
+            Assert.Equal(xs.Average(), await ys.Average());
+            Assert.Equal(xs.Average(), await ys.Average(x => x));
         }
 
         [Fact]
-        public void Average7()
+        public async Task Average7()
         {
             var xs = new[] { 1.0f, 2.0f, 3.0f };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Average(), ys.Average().Result);
-            Assert.Equal(xs.Average(), ys.Average(x => x).Result);
+            Assert.Equal(xs.Average(), await ys.Average());
+            Assert.Equal(xs.Average(), await ys.Average(x => x));
         }
 
         [Fact]
-        public void Average8()
+        public async Task Average8()
         {
             var xs = new[] { 1.0f, default(float?), 3.0f };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Average(), ys.Average().Result);
-            Assert.Equal(xs.Average(), ys.Average(x => x).Result);
+            Assert.Equal(xs.Average(), await ys.Average());
+            Assert.Equal(xs.Average(), await ys.Average(x => x));
         }
 
         [Fact]
-        public void Average9()
+        public async Task Average9()
         {
             var xs = new[] { 1.0m, 2.0m, 3.0m };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Average(), ys.Average().Result);
-            Assert.Equal(xs.Average(), ys.Average(x => x).Result);
+            Assert.Equal(xs.Average(), await ys.Average());
+            Assert.Equal(xs.Average(), await ys.Average(x => x));
         }
 
         [Fact]
-        public void Average10()
+        public async Task Average10()
         {
             var xs = new[] { 1.0m, default(decimal?), 3.0m };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Average(), ys.Average().Result);
-            Assert.Equal(xs.Average(), ys.Average(x => x).Result);
+            Assert.Equal(xs.Average(), await ys.Average());
+            Assert.Equal(xs.Average(), await ys.Average(x => x));
         }
 
         [Fact]
-        public void Average11()
+        public async Task Average11()
         {
             var xs = new int[0];
             var ys = xs.ToAsyncEnumerable();
-            AssertThrows<Exception>(() => ys.Average().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await Assert.ThrowsAsync<InvalidOperationException>(() => ys.Average());
         }
 
         [Fact]
-        public void Average12()
+        public async Task Average12()
         {
             var xs = new int?[0];
             var ys = xs.ToAsyncEnumerable();
-            Assert.Null(ys.Average().Result);
+            Assert.Null(await ys.Average());
         }
 
         [Fact]
-        public void Average13()
+        public async Task Average13()
         {
             var xs = new long[0];
             var ys = xs.ToAsyncEnumerable();
-            AssertThrows<Exception>(() => ys.Average().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await Assert.ThrowsAsync<InvalidOperationException>(() => ys.Average());
         }
 
         [Fact]
-        public void Average14()
+        public async Task Average14()
         {
             var xs = new long?[0];
             var ys = xs.ToAsyncEnumerable();
-            Assert.Null(ys.Average().Result);
+            Assert.Null(await ys.Average());
         }
 
         [Fact]
-        public void Average15()
+        public async Task Average15()
         {
             var xs = new double[0];
             var ys = xs.ToAsyncEnumerable();
-            AssertThrows<Exception>(() => ys.Average().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await Assert.ThrowsAsync<InvalidOperationException>(() => ys.Average());
         }
 
         [Fact]
-        public void Average16()
+        public async Task Average16()
         {
             var xs = new double?[0];
             var ys = xs.ToAsyncEnumerable();
-            Assert.Null(ys.Average().Result);
+            Assert.Null(await ys.Average());
         }
 
         [Fact]
-        public void Average17()
+        public async Task Average17()
         {
             var xs = new float[0];
             var ys = xs.ToAsyncEnumerable();
-            AssertThrows<Exception>(() => ys.Average().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await Assert.ThrowsAsync<InvalidOperationException>(() => ys.Average());
         }
 
         [Fact]
-        public void Average18()
+        public async Task Average18()
         {
             var xs = new float?[0];
             var ys = xs.ToAsyncEnumerable();
-            Assert.Null(ys.Average().Result);
+            Assert.Null(await ys.Average());
         }
 
         [Fact]
-        public void Average19()
+        public async Task Average19()
         {
             var xs = new decimal[0];
             var ys = xs.ToAsyncEnumerable();
-            AssertThrows<Exception>(() => ys.Average().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await Assert.ThrowsAsync<InvalidOperationException>(() => ys.Average());
         }
 
         [Fact]
-        public void Average20()
+        public async Task Average20()
         {
             var xs = new decimal?[0];
             var ys = xs.ToAsyncEnumerable();
-            Assert.Null(ys.Average().Result);
+            Assert.Null(await ys.Average());
         }
     }
 }

+ 8 - 8
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Cast.cs

@@ -3,8 +3,8 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 using Xunit;
 
 namespace Tests
@@ -14,21 +14,21 @@ namespace Tests
         [Fact]
         public void Cast_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Cast<int>(default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Cast<int>(default));
         }
 
         [Fact]
-        public void Cast1()
+        public async Task Cast1()
         {
             var xs = new object[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
             var ys = xs.Cast<int>();
 
             var e = ys.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await NoNextAsync(e);
         }
 
         [Fact]

+ 30 - 30
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Concat.cs

@@ -15,50 +15,50 @@ namespace Tests
         [Fact]
         public void Concat_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Concat<int>(default, Return42));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Concat<int>(Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Concat(default, Return42));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Concat(Return42, default));
         }
 
         [Fact]
-        public void Concat1()
+        public async Task Concat1Async()
         {
             var ys = new[] { 1, 2, 3 }.ToAsyncEnumerable().Concat(new[] { 4, 5, 6 }.ToAsyncEnumerable());
 
             var e = ys.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Concat2()
+        public async Task Concat2Async()
         {
             var ex = new Exception("Bang");
             var ys = new[] { 1, 2, 3 }.ToAsyncEnumerable().Concat(Throw<int>(ex));
 
             var e = ys.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Concat3()
+        public async Task Concat3Async()
         {
             var ex = new Exception("Bang");
             var ys = Throw<int>(ex).Concat(new[] { 4, 5, 6 }.ToAsyncEnumerable());
 
             var e = ys.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Concat7()
+        public async Task Concat7Async()
         {
             var ws = new[] { 1, 2, 3 }.ToAsyncEnumerable();
             var xs = new[] { 4, 5 }.ToAsyncEnumerable();
@@ -68,18 +68,18 @@ namespace Tests
             var res = ws.Concat(xs).Concat(ys).Concat(zs);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            HasNext(e, 5);
-            HasNext(e, 6);
-            HasNext(e, 7);
-            HasNext(e, 8);
-            HasNext(e, 9);
-            HasNext(e, 10);
-            HasNext(e, 11);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 6);
+            await HasNextAsync(e, 7);
+            await HasNextAsync(e, 8);
+            await HasNextAsync(e, 9);
+            await HasNextAsync(e, 10);
+            await HasNextAsync(e, 11);
+            await NoNextAsync(e);
         }
 
         [Fact]

+ 12 - 14
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Contains.cs

@@ -16,45 +16,43 @@ namespace Tests
         [Fact]
         public async Task Contains_Null()
         {
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Contains<int>(default, 42));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Contains<int>(default, 42, EqualityComparer<int>.Default));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Contains<int>(Return42, 42, null));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Contains(default, 42));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Contains(default, 42, EqualityComparer<int>.Default));
 
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Contains<int>(default, 42, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Contains<int>(default, 42, EqualityComparer<int>.Default, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Contains<int>(Return42, 42, null, CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Contains(default, 42, CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Contains(default, 42, EqualityComparer<int>.Default, CancellationToken.None));
         }
 
         [Fact]
-        public void Contains1()
+        public async Task Contains1Async()
         {
             var xs = new[] { 1, 2, 3, 4, 5 }.ToAsyncEnumerable();
             var ys = xs.Contains(3);
-            Assert.True(ys.Result);
+            Assert.True(await ys);
         }
 
         [Fact]
-        public void Contains2()
+        public async Task Contains2Async()
         {
             var xs = new[] { 1, 2, 3, 4, 5 }.ToAsyncEnumerable();
             var ys = xs.Contains(6);
-            Assert.False(ys.Result);
+            Assert.False(await ys);
         }
 
         [Fact]
-        public void Contains3()
+        public async Task Contains3Async()
         {
             var xs = new[] { 1, 2, 3, 4, 5 }.ToAsyncEnumerable();
             var ys = xs.Contains(-3, new Eq());
-            Assert.True(ys.Result);
+            Assert.True(await ys);
         }
 
         [Fact]
-        public void Contains4()
+        public async Task Contains4Async()
         {
             var xs = new[] { 1, 2, 3, 4, 5 }.ToAsyncEnumerable();
             var ys = xs.Contains(-6, new Eq());
-            Assert.False(ys.Result);
+            Assert.False(await ys);
         }
 
         private sealed class Eq : IEqualityComparer<int>

+ 24 - 13
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Count.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -18,35 +17,47 @@ namespace Tests
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Count<int>(default));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Count<int>(default, x => true));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Count<int>(Return42, default(Func<int, bool>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Count(Return42, default(Func<int, bool>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Count<int>(default, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Count<int>(default, x => true, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Count<int>(Return42, default(Func<int, bool>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Count(Return42, default(Func<int, bool>), CancellationToken.None));
         }
 
         [Fact]
-        public void Count1()
+        public async Task Count1()
         {
-            Assert.Equal(0, new int[0].ToAsyncEnumerable().Count().Result);
-            Assert.Equal(3, new[] { 1, 2, 3 }.ToAsyncEnumerable().Count().Result);
-            AssertThrows<AggregateException>(() => Throw<int>(new Exception("Bang!")).Count().Wait(WaitTimeoutMs));
+            Assert.Equal(0, await new int[0].ToAsyncEnumerable().Count());
+            Assert.Equal(3, await new[] { 1, 2, 3 }.ToAsyncEnumerable().Count());
         }
 
         [Fact]
-        public void Count2()
+        public async Task Count2()
         {
-            Assert.Equal(0, new int[0].ToAsyncEnumerable().Count(x => x < 3).Result);
-            Assert.Equal(2, new[] { 1, 2, 3 }.ToAsyncEnumerable().Count(x => x < 3).Result);
-            AssertThrows<AggregateException>(() => Throw<int>(new Exception("Bang!")).Count(x => x < 3).Wait(WaitTimeoutMs));
+            Assert.Equal(0, await new int[0].ToAsyncEnumerable().Count(x => x < 3));
+            Assert.Equal(2, await new[] { 1, 2, 3 }.ToAsyncEnumerable().Count(x => x < 3));
         }
 
         [Fact]
-        public void Count3()
+        public async Task Count3Async()
         {
             var ex = new Exception("Bang!");
             var ys = new[] { 1, 2, 3 }.ToAsyncEnumerable().Count(new Func<int, bool>(x => { throw ex; }));
-            AssertThrows<Exception>(() => ys.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(ys, ex);
+        }
+
+        [Fact]
+        public async Task Count4Async()
+        {
+            var ex = new Exception("Bang!");
+            await AssertThrowsAsync(Throw<int>(ex).Count(), ex);
+        }
+
+        [Fact]
+        public async Task Count5Async()
+        {
+            var ex = new Exception("Bang!");
+            await AssertThrowsAsync(Throw<int>(ex).Count(x => x < 3), ex);
         }
     }
 }

+ 1 - 4
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/CreateEnumerable.cs

@@ -3,9 +3,7 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Threading;
 using Xunit;
 
 namespace Tests
@@ -15,8 +13,7 @@ namespace Tests
         [Fact]
         public void CreateEnumerable_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.CreateEnumerable<int>(default(Func<IAsyncEnumerator<int>>)));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.CreateEnumerable<int>(default(Func<CancellationToken, IAsyncEnumerator<int>>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.CreateEnumerable<int>(default));
         }
     }
 }

+ 3 - 3
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/CreateEnumerator.cs

@@ -15,17 +15,17 @@ namespace Tests
         [Fact]
         public void CreateEnumerator_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.CreateEnumerator<int>(default, () => 3, () => TaskExt.CompletedTask));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.CreateEnumerator(default, () => 3, () => new ValueTask()));
         }
 
         [Fact]
         public void CreateEnumerator_Throws()
         {
-            var iter = AsyncEnumerable.CreateEnumerator<int>(() => TaskExt.True, () => 3, () => TaskExt.CompletedTask);
+            var iter = AsyncEnumerable.CreateEnumerator(() => new ValueTask<bool>(false), () => 3, () => new ValueTask());
 
             var enu = (IAsyncEnumerable<int>)iter;
 
-            AssertThrows<NotSupportedException>(() => enu.GetAsyncEnumerator());
+            Assert.Throws<NotSupportedException>(() => enu.GetAsyncEnumerator());
         }
     }
 }

+ 30 - 30
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/DefaultIfEmpty.cs

@@ -15,94 +15,94 @@ namespace Tests
         [Fact]
         public void DefaultIfEmpty_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.DefaultIfEmpty<int>(default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.DefaultIfEmpty<int>(default, 42));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.DefaultIfEmpty<int>(default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.DefaultIfEmpty(default, 42));
         }
 
         [Fact]
-        public void DefaultIfEmpty1()
+        public async Task DefaultIfEmpty1()
         {
             var xs = AsyncEnumerable.Empty<int>().DefaultIfEmpty();
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 0);
-            NoNext(e);
+            await HasNextAsync(e, 0);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void DefaultIfEmpty2()
+        public async Task DefaultIfEmpty2()
         {
             var xs = AsyncEnumerable.Empty<int>().DefaultIfEmpty(42);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 42);
-            NoNext(e);
+            await HasNextAsync(e, 42);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void DefaultIfEmpty3()
+        public async Task DefaultIfEmpty3()
         {
             var xs = Return42.DefaultIfEmpty();
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 42);
-            NoNext(e);
+            await HasNextAsync(e, 42);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void DefaultIfEmpty4()
+        public async Task DefaultIfEmpty4()
         {
             var xs = Return42.DefaultIfEmpty(24);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 42);
-            NoNext(e);
+            await HasNextAsync(e, 42);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void DefaultIfEmpty5()
+        public async Task DefaultIfEmpty5()
         {
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable().DefaultIfEmpty();
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void DefaultIfEmpty6()
+        public async Task DefaultIfEmpty6()
         {
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable().DefaultIfEmpty(24);
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 4);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 4);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void DefaultIfEmpty7()
+        public async Task DefaultIfEmpty7Async()
         {
             var ex = new Exception("Bang!");
             var xs = Throw<int>(ex).DefaultIfEmpty();
 
             var e = xs.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void DefaultIfEmpty8()
+        public async Task DefaultIfEmpty8Async()
         {
             var ex = new Exception("Bang!");
             var xs = Throw<int>(ex).DefaultIfEmpty(24);
 
             var e = xs.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]

+ 18 - 19
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Distinct.cs

@@ -15,37 +15,36 @@ namespace Tests
         [Fact]
         public void Distinct_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Distinct<int>(default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Distinct<int>(default, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Distinct<int>(Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Distinct<int>(default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Distinct(default, EqualityComparer<int>.Default));
         }
 
         [Fact]
-        public void Distinct1()
+        public async Task Distinct1()
         {
             var xs = new[] { 1, 2, 1, 3, 5, 2, 1, 4 }.ToAsyncEnumerable().Distinct();
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 2);
-            HasNext(e, 3);
-            HasNext(e, 5);
-            HasNext(e, 4);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 4);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Distinct2()
+        public async Task Distinct2()
         {
             var xs = new[] { 1, -2, -1, 3, 5, 2, 1, 4 }.ToAsyncEnumerable().Distinct(new Eq());
 
             var e = xs.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, -2);
-            HasNext(e, 3);
-            HasNext(e, 5);
-            HasNext(e, 4);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, -2);
+            await HasNextAsync(e, 3);
+            await HasNextAsync(e, 5);
+            await HasNextAsync(e, 4);
+            await NoNextAsync(e);
         }
 
         [Fact]
@@ -83,13 +82,13 @@ namespace Tests
         }
 
         [Fact]
-        public void Distinct12()
+        public async Task Distinct12()
         {
             var xs = AsyncEnumerable.Empty<int>().Distinct();
 
             var e = xs.GetAsyncEnumerator();
 
-            NoNext(e);
+            await NoNextAsync(e);
         }
 
         private sealed class Eq : IEqualityComparer<int>

+ 14 - 15
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/ElementAt.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -17,53 +16,53 @@ namespace Tests
         public async Task ElementAt_Null()
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ElementAt<int>(default, 0));
-            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => AsyncEnumerable.ElementAt<int>(Return42, -1));
+            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => AsyncEnumerable.ElementAt(Return42, -1));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ElementAt<int>(default, 0, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => AsyncEnumerable.ElementAt<int>(Return42, -1, CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => AsyncEnumerable.ElementAt(Return42, -1, CancellationToken.None));
         }
 
         [Fact]
-        public void ElementAt1()
+        public async Task ElementAt1Async()
         {
             var res = AsyncEnumerable.Empty<int>().ElementAt(0);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is ArgumentOutOfRangeException);
+            await AssertThrowsAsync<ArgumentOutOfRangeException>(res);
         }
 
         [Fact]
-        public void ElementAt2()
+        public async Task ElementAt2Async()
         {
             var res = Return42.ElementAt(0);
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void ElementAt3()
+        public async Task ElementAt3Async()
         {
             var res = Return42.ElementAt(1);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is ArgumentOutOfRangeException);
+            await AssertThrowsAsync<ArgumentOutOfRangeException>(res);
         }
 
         [Fact]
-        public void ElementAt4()
+        public async Task ElementAt4Async()
         {
             var res = new[] { 1, 42, 3 }.ToAsyncEnumerable().ElementAt(1);
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void ElementAt5()
+        public async Task ElementAt5Async()
         {
             var res = new[] { 1, 42, 3 }.ToAsyncEnumerable().ElementAt(7);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is ArgumentOutOfRangeException);
+            await AssertThrowsAsync<ArgumentOutOfRangeException>(res);
         }
 
         [Fact]
-        public void ElementAt6()
+        public async Task ElementAt6Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).ElementAt(15);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
     }
 }

+ 19 - 16
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/ElementAtOrDefault.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -17,53 +16,57 @@ namespace Tests
         public async Task ElementAtOrDefault_Null()
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ElementAtOrDefault<int>(default, 0));
-            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => AsyncEnumerable.ElementAtOrDefault<int>(Return42, -1));
-
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ElementAtOrDefault<int>(default, 0, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => AsyncEnumerable.ElementAtOrDefault<int>(Return42, -1, CancellationToken.None));
         }
 
         [Fact]
-        public void ElementAtOrDefault1()
+        public async Task ElementAtOrDefault1Async()
         {
             var res = AsyncEnumerable.Empty<int>().ElementAtOrDefault(0);
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
         }
 
         [Fact]
-        public void ElementAtOrDefault2()
+        public async Task ElementAtOrDefault2Async()
         {
             var res = Return42.ElementAtOrDefault(0);
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void ElementAtOrDefault3()
+        public async Task ElementAtOrDefault3Async()
         {
             var res = Return42.ElementAtOrDefault(1);
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
         }
 
         [Fact]
-        public void ElementAtOrDefault4()
+        public async Task ElementAtOrDefault4Async()
         {
             var res = new[] { 1, 42, 3 }.ToAsyncEnumerable().ElementAtOrDefault(1);
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void ElementAtOrDefault5()
+        public async Task ElementAtOrDefault5Async()
         {
             var res = new[] { 1, 42, 3 }.ToAsyncEnumerable().ElementAtOrDefault(7);
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
+        }
+
+        [Fact]
+        public async Task ElementAtOrDefault6Async()
+        {
+            var res = Return42.ElementAtOrDefault(-1);
+            Assert.Equal(0, await res);
         }
 
         [Fact]
-        public void ElementAtOrDefault6()
+        public async Task ElementAtOrDefault7Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).ElementAtOrDefault(15);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
     }
 }

+ 3 - 12
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Empty.cs

@@ -2,8 +2,8 @@
 // The .NET Foundation licenses this file to you under the Apache 2.0 License.
 // See the LICENSE file in the project root for more information. 
 
-using System;
 using System.Linq;
+using System.Threading.Tasks;
 using Xunit;
 
 namespace Tests
@@ -11,19 +11,10 @@ namespace Tests
     public class Empty : AsyncEnumerableTests
     {
         [Fact]
-        public void Empty1()
+        public async Task Empty1()
         {
             var xs = AsyncEnumerable.Empty<int>();
-            NoNext(xs.GetAsyncEnumerator());
-        }
-
-        [Fact]
-        public void Empty2()
-        {
-            var xs = AsyncEnumerable.Empty<int>();
-
-            var e = xs.GetAsyncEnumerator();
-            Assert.False(e.MoveNextAsync().Result);
+            await NoNextAsync(xs.GetAsyncEnumerator());
         }
     }
 }

+ 10 - 11
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Except.cs

@@ -15,36 +15,35 @@ namespace Tests
         [Fact]
         public void Except_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Except<int>(default, Return42));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Except<int>(Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Except(default, Return42));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Except(Return42, default));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Except<int>(default, Return42, new Eq()));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Except<int>(Return42, null, new Eq()));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Except<int>(Return42, Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Except(default, Return42, new Eq()));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Except(Return42, null, new Eq()));
         }
 
         [Fact]
-        public void Except1()
+        public async Task Except1()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
             var ys = new[] { 3, 5, 1, 4 }.ToAsyncEnumerable();
             var res = xs.Except(ys);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 2);
-            NoNext(e);
+            await HasNextAsync(e, 2);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Except2()
+        public async Task Except2()
         {
             var xs = new[] { 1, 2, -3 }.ToAsyncEnumerable();
             var ys = new[] { 3, 5, -1, 4 }.ToAsyncEnumerable();
             var res = xs.Except(ys, new Eq());
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 2);
-            NoNext(e);
+            await HasNextAsync(e, 2);
+            await NoNextAsync(e);
         }
 
         [Fact]

+ 20 - 21
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/First.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -18,76 +17,76 @@ namespace Tests
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.First<int>(default));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.First<int>(default, x => true));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.First<int>(Return42, default(Func<int, bool>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.First(Return42, default(Func<int, bool>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.First<int>(default, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.First<int>(default, x => true, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.First<int>(Return42, default(Func<int, bool>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.First(Return42, default(Func<int, bool>), CancellationToken.None));
         }
 
         [Fact]
-        public void First1()
+        public async Task First1Async()
         {
             var res = AsyncEnumerable.Empty<int>().First();
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await AssertThrowsAsync<InvalidOperationException>(res);
         }
 
         [Fact]
-        public void First2()
+        public async Task First2Async()
         {
             var res = AsyncEnumerable.Empty<int>().First(x => true);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await AssertThrowsAsync<InvalidOperationException>(res);
         }
 
         [Fact]
-        public void First3()
+        public async Task First3Async()
         {
             var res = Return42.First(x => x % 2 != 0);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await AssertThrowsAsync<InvalidOperationException>(res);
         }
 
         [Fact]
-        public void First4()
+        public async Task First4Async()
         {
             var res = Return42.First();
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void First5()
+        public async Task First5Async()
         {
             var res = Return42.First(x => x % 2 == 0);
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void First6()
+        public async Task First6Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).First();
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void First7()
+        public async Task First7Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).First(x => true);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void First8()
+        public async Task First8Async()
         {
             var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().First();
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void First9()
+        public async Task First9Async()
         {
             var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().First(x => x % 2 != 0);
-            Assert.Equal(45, res.Result);
+            Assert.Equal(45, await res);
         }
     }
 }

+ 22 - 23
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/FirstOrDefault.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -18,83 +17,83 @@ namespace Tests
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.FirstOrDefault<int>(default));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.FirstOrDefault<int>(default, x => true));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.FirstOrDefault<int>(Return42, default(Func<int, bool>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.FirstOrDefault(Return42, default(Func<int, bool>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.FirstOrDefault<int>(default, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.FirstOrDefault<int>(default, x => true, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.FirstOrDefault<int>(Return42, default(Func<int, bool>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.FirstOrDefault(Return42, default(Func<int, bool>), CancellationToken.None));
         }
 
         [Fact]
-        public void FirstOrDefault1()
+        public async Task FirstOrDefault1Async()
         {
             var res = AsyncEnumerable.Empty<int>().FirstOrDefault();
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
         }
 
         [Fact]
-        public void FirstOrDefault2()
+        public async Task FirstOrDefault2Async()
         {
             var res = AsyncEnumerable.Empty<int>().FirstOrDefault(x => true);
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
         }
 
         [Fact]
-        public void FirstOrDefault3()
+        public async Task FirstOrDefault3Async()
         {
             var res = Return42.FirstOrDefault(x => x % 2 != 0);
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
         }
 
         [Fact]
-        public void FirstOrDefault4()
+        public async Task FirstOrDefault4Async()
         {
             var res = Return42.FirstOrDefault();
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void FirstOrDefault5()
+        public async Task FirstOrDefault5Async()
         {
             var res = Return42.FirstOrDefault(x => x % 2 == 0);
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void FirstOrDefault6()
+        public async Task FirstOrDefault6Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).FirstOrDefault();
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void FirstOrDefault7()
+        public async Task FirstOrDefault7Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).FirstOrDefault(x => true);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void FirstOrDefault8()
+        public async Task FirstOrDefault8Async()
         {
             var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().FirstOrDefault();
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void FirstOrDefault9()
+        public async Task FirstOrDefault9Async()
         {
             var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().FirstOrDefault(x => x % 2 != 0);
-            Assert.Equal(45, res.Result);
+            Assert.Equal(45, await res);
         }
 
         [Fact]
-        public void FirstOrDefault10()
+        public async Task FirstOrDefault10Async()
         {
             var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().FirstOrDefault(x => x < 10);
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
         }
     }
 }

+ 18 - 17
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/ForEachAsync.cs

@@ -2,8 +2,8 @@
 // The .NET Foundation licenses this file to you under the Apache 2.0 License.
 // See the LICENSE file in the project root for more information. 
 
+#if !HAS_AWAIT_FOREACH
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -17,70 +17,71 @@ namespace Tests
         public async Task ForEachAsync_Null()
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(default, x => { }));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(Return42, default(Action<int>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync(Return42, default(Action<int>)));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(default, (x, i) => { }));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(Return42, default(Action<int, int>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync(Return42, default(Action<int, int>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(default, x => { }, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(Return42, default(Action<int>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync(Return42, default(Action<int>), CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(default, (x, i) => { }, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(Return42, default(Action<int, int>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync(Return42, default(Action<int, int>), CancellationToken.None));
         }
 
         [Fact]
-        public void ForEachAsync1()
+        public async Task ForEachAsync1()
         {
             var sum = 0;
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
 
-            xs.ForEachAsync(x => sum += x).Wait(WaitTimeoutMs);
+            await xs.ForEachAsync(x => sum += x);
             Assert.Equal(10, sum);
         }
 
         [Fact]
-        public void ForEachAsync2()
+        public async Task ForEachAsync2()
         {
             var sum = 0;
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
 
-            xs.ForEachAsync((x, i) => sum += x * i).Wait(WaitTimeoutMs);
+            await xs.ForEachAsync((x, i) => sum += x * i);
             Assert.Equal(1 * 0 + 2 * 1 + 3 * 2 + 4 * 3, sum);
         }
 
         [Fact]
-        public void ForEachAsync3()
+        public async Task ForEachAsync3Async()
         {
             var ex = new Exception("Bang");
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
 
-            AssertThrows<Exception>(() => xs.ForEachAsync(x => { throw ex; }).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(xs.ForEachAsync(x => { throw ex; }), ex);
         }
 
         [Fact]
-        public void ForEachAsync4()
+        public async Task ForEachAsync4Async()
         {
             var ex = new Exception("Bang");
             var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
 
-            AssertThrows<Exception>(() => xs.ForEachAsync((x, i) => { throw ex; }).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(xs.ForEachAsync((x, i) => { throw ex; }), ex);
         }
 
         [Fact]
-        public void ForEachAsync5()
+        public async Task ForEachAsync5Async()
         {
             var ex = new Exception("Bang");
             var xs = Throw<int>(ex);
 
-            AssertThrows<Exception>(() => xs.ForEachAsync(x => { throw ex; }).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(xs.ForEachAsync(x => { throw ex; }), ex);
         }
 
         [Fact]
-        public void ForEachAsync6()
+        public async Task ForEachAsync6Async()
         {
             var ex = new Exception("Bang");
             var xs = Throw<int>(ex);
 
-            AssertThrows<Exception>(() => xs.ForEachAsync((x, i) => { throw ex; }).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(xs.ForEachAsync((x, i) => { throw ex; }), ex);
         }
     }
 }
+#endif

+ 177 - 220
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.cs

@@ -15,45 +15,41 @@ namespace Tests
         [Fact]
         public void GroupBy_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int>(default, x => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int>(Return42, default(Func<int, int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int>(default, x => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy(Return42, default(Func<int, int>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int>(default, x => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int>(Return42, default(Func<int, int>), EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int>(Return42, x => x, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int>(default, x => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy(Return42, default(Func<int, int>), EqualityComparer<int>.Default));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(default, x => x, x => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, default, x => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, x => x, default(Func<int, int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(default, x => x, x => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, default, x => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy(Return42, x => x, default(Func<int, int>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(default, x => x, x => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, default, x => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, x => x, default(Func<int, int>), EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, x => x, x => x, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(default, x => x, x => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy(Return42, default, x => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy(Return42, x => x, default(Func<int, int>), EqualityComparer<int>.Default));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(default, x => x, (x, ys) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, default, (x, ys) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, x => x, default(Func<int, IAsyncEnumerable<int>, int>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(default, x => x, (x, ys) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, default, (x, ys) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy(Return42, x => x, default(Func<int, IAsyncEnumerable<int>, int>)));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(default, x => x, (x, ys) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, default, (x, ys) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, x => x, default(Func<int, IAsyncEnumerable<int>, int>), EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(Return42, x => x, (x, ys) => x, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int>(default, x => x, (x, ys) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy(Return42, default, (x, ys) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy(Return42, x => x, default(Func<int, IAsyncEnumerable<int>, int>), EqualityComparer<int>.Default));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(default, x => x, x => x, (x, ys) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, default, x => x, (x, ys) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, x => x, default, (x, ys) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, x => x, x => x, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(default, x => x, x => x, (x, ys) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, default, x => x, (x, ys) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, x => x, default, (x, ys) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, x => x, x => x, default));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(default, x => x, x => x, (x, ys) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, default, x => x, (x, ys) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, x => x, default, (x, ys) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, x => x, x => x, default, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, x => x, x => x, (x, ys) => x, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(default, x => x, x => x, (x, ys) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy(Return42, default, x => x, (x, ys) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, x => x, default, (x, ys) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<int, int, int, int>(Return42, x => x, x => x, default, EqualityComparer<int>.Default));
         }
 
         [Fact]
-        public void GroupBy1()
+        public async Task GroupBy1()
         {
             var xs = new[] {
                 new { Name = "Bart", Age = 27 },
@@ -71,38 +67,38 @@ namespace Tests
 
             var e = res.GetAsyncEnumerator();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.Equal(2, e.Current.Key);
             var g1 = e.Current.GetAsyncEnumerator();
-            HasNext(g1, xs[0]);
-            HasNext(g1, xs[2]);
-            HasNext(g1, xs[4]);
-            HasNext(g1, xs[5]);
-            NoNext(g1);
+            await HasNextAsync(g1, xs[0]);
+            await HasNextAsync(g1, xs[2]);
+            await HasNextAsync(g1, xs[4]);
+            await HasNextAsync(g1, xs[5]);
+            await NoNextAsync(g1);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.Equal(6, e.Current.Key);
             var g2 = e.Current.GetAsyncEnumerator();
-            HasNext(g2, xs[1]);
-            NoNext(g2);
+            await HasNextAsync(g2, xs[1]);
+            await NoNextAsync(g2);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.Equal(1, e.Current.Key);
             var g3 = e.Current.GetAsyncEnumerator();
-            HasNext(g3, xs[3]);
-            NoNext(g3);
+            await HasNextAsync(g3, xs[3]);
+            await NoNextAsync(g3);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             Assert.Equal(4, e.Current.Key);
             var g4 = e.Current.GetAsyncEnumerator();
-            HasNext(g4, xs[6]);
-            NoNext(g4);
+            await HasNextAsync(g4, xs[6]);
+            await NoNextAsync(g4);
 
-            NoNext(e);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void GroupBy2()
+        public async Task GroupBy2()
         {
             var xs = new[] {
                 new { Name = "Bart", Age = 27 },
@@ -120,325 +116,286 @@ namespace Tests
 
             var e = res.GetAsyncEnumerator();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g1 = e.Current;
             Assert.Equal(2, g1.Key);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g2 = e.Current;
             Assert.Equal(6, g2.Key);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g3 = e.Current;
             Assert.Equal(1, g3.Key);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g4 = e.Current;
             Assert.Equal(4, g4.Key);
 
-            NoNext(e);
+            await NoNextAsync(e);
 
             var g1e = g1.GetAsyncEnumerator();
-            HasNext(g1e, xs[0]);
-            HasNext(g1e, xs[2]);
-            HasNext(g1e, xs[4]);
-            HasNext(g1e, xs[5]);
-            NoNext(g1e);
+            await HasNextAsync(g1e, xs[0]);
+            await HasNextAsync(g1e, xs[2]);
+            await HasNextAsync(g1e, xs[4]);
+            await HasNextAsync(g1e, xs[5]);
+            await NoNextAsync(g1e);
 
             var g2e = g2.GetAsyncEnumerator();
-            HasNext(g2e, xs[1]);
-            NoNext(g2e);
+            await HasNextAsync(g2e, xs[1]);
+            await NoNextAsync(g2e);
 
             var g3e = g3.GetAsyncEnumerator();
-            HasNext(g3e, xs[3]);
-            NoNext(g3e);
+            await HasNextAsync(g3e, xs[3]);
+            await NoNextAsync(g3e);
 
             var g4e = g4.GetAsyncEnumerator();
-            HasNext(g4e, xs[6]);
-            NoNext(g4e);
+            await HasNextAsync(g4e, xs[6]);
+            await NoNextAsync(g4e);
         }
 
         [Fact]
-        public void GroupBy3()
+        public async Task GroupBy3()
         {
             var xs = AsyncEnumerable.Empty<int>();
             var ys = xs.GroupBy(x => x);
 
             var e = ys.GetAsyncEnumerator();
-            NoNext(e);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void GroupBy4()
+        public async Task GroupBy4Async()
         {
             var ex = new Exception("Bang!");
             var xs = Throw<int>(ex);
             var ys = xs.GroupBy(x => x);
 
             var e = ys.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void GroupBy5()
+        public async Task GroupBy5Async()
         {
-            var xs = GetXs().ToAsyncEnumerable();
+            var ex = new Exception("Bang!");
+            var xs = GetXs(ex).ToAsyncEnumerable();
             var ys = xs.GroupBy(x => x);
 
             var e = ys.GetAsyncEnumerator();
 
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single().Message == "Bang!");
-
-            //Assert.True(e.MoveNext().Result);
-            //var g1 = e.Current;
-            //Assert.Equal(g1.Key, 42);
-            //var g1e = g1.GetEnumerator();
-            //HasNext(g1e, 42);
-
-            //Assert.True(e.MoveNext().Result);
-            //var g2 = e.Current;
-            //Assert.Equal(g2.Key, 43);
-            //var g2e = g2.GetEnumerator();
-            //HasNext(g2e, 43);
-
-
-            //AssertThrows<Exception>(() => g1e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single().Message == "Bang!");
-            //AssertThrows<Exception>(() => g2e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single().Message == "Bang!");
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void GroupBy6()
+        public async Task GroupBy6Async()
         {
-            var xs = GetXs().ToAsyncEnumerable();
+            var ex = new Exception("Bang!");
+            var xs = GetXs(ex).ToAsyncEnumerable();
             var ys = xs.GroupBy(x => x);
 
             var e = ys.GetAsyncEnumerator();
 
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single().Message == "Bang!");
-
-            //Assert.True(e.MoveNext().Result);
-            //var g1 = e.Current;
-            //Assert.Equal(g1.Key, 42);
-            //var g1e = g1.GetEnumerator();
-            //HasNext(g1e, 42);
-            //AssertThrows<Exception>(() => g1e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single().Message == "Bang!");
-
-
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
-        private static IEnumerable<int> GetXs()
+        private static IEnumerable<int> GetXs(Exception ex)
         {
             yield return 42;
             yield return 43;
-            throw new Exception("Bang!");
+            throw ex;
         }
 
         [Fact]
-        public void GroupBy7()
+        public async Task GroupBy7Async()
         {
             var ex = new Exception("Bang!");
             var xs = Return42;
-            var ys = xs.GroupBy<int, int>(new Func<int, int>(x => { throw ex; }));
+            var ys = xs.GroupBy(new Func<int, int>(x => { throw ex; }));
 
             var e = ys.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void GroupBy8()
+        public async Task GroupBy8Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
-            var ys = xs.GroupBy<int, int>(x => { if (x == 3) throw ex; return x; });
+            var ys = xs.GroupBy(x => { if (x == 3) throw ex; return x; });
 
             var e = ys.GetAsyncEnumerator();
 
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
-
-            //Assert.True(e.MoveNext().Result);
-            //var g1 = e.Current;
-            //Assert.Equal(g1.Key, 1);
-            //var g1e = g1.GetEnumerator();
-            //HasNext(g1e, 1);
-
-            //Assert.True(e.MoveNext().Result);
-            //var g2 = e.Current;
-            //Assert.Equal(g2.Key, 2);
-            //var g2e = g2.GetEnumerator();
-            //HasNext(g2e, 2);
-
-
-            //AssertThrows<Exception>(() => g1e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
-            //AssertThrows<Exception>(() => g2e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void GroupBy9()
+        public async Task GroupBy9()
         {
             var xs = AsyncEnumerable.Range(0, 10);
             var ys = xs.GroupBy(x => x % 3, x => (char)('a' + x));
 
             var e = ys.GetAsyncEnumerator();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g1 = e.Current;
             Assert.Equal(0, g1.Key);
             var g1e = g1.GetAsyncEnumerator();
-            HasNext(g1e, 'a');
-            HasNext(g1e, 'd');
-            HasNext(g1e, 'g');
-            HasNext(g1e, 'j');
-            NoNext(g1e);
+            await HasNextAsync(g1e, 'a');
+            await HasNextAsync(g1e, 'd');
+            await HasNextAsync(g1e, 'g');
+            await HasNextAsync(g1e, 'j');
+            await NoNextAsync(g1e);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g2 = e.Current;
             Assert.Equal(1, g2.Key);
             var g2e = g2.GetAsyncEnumerator();
-            HasNext(g2e, 'b');
-            HasNext(g2e, 'e');
-            HasNext(g2e, 'h');
-            NoNext(g2e);
+            await HasNextAsync(g2e, 'b');
+            await HasNextAsync(g2e, 'e');
+            await HasNextAsync(g2e, 'h');
+            await NoNextAsync(g2e);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g3 = e.Current;
             Assert.Equal(2, g3.Key);
             var g3e = g3.GetAsyncEnumerator();
-            HasNext(g3e, 'c');
-            HasNext(g3e, 'f');
-            HasNext(g3e, 'i');
-            NoNext(g3e);
+            await HasNextAsync(g3e, 'c');
+            await HasNextAsync(g3e, 'f');
+            await HasNextAsync(g3e, 'i');
+            await NoNextAsync(g3e);
 
-            NoNext(e);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void GroupBy10()
+        public async Task GroupBy10()
         {
             var xs = AsyncEnumerable.Range(0, 10);
             var ys = xs.GroupBy(x => x % 3, x => (char)('a' + x), (k, cs) => k + " - " + cs.Aggregate("", (a, c) => a + c).Result);
 
             var e = ys.GetAsyncEnumerator();
-            HasNext(e, "0 - adgj");
-            HasNext(e, "1 - beh");
-            HasNext(e, "2 - cfi");
-            NoNext(e);
+            await HasNextAsync(e, "0 - adgj");
+            await HasNextAsync(e, "1 - beh");
+            await HasNextAsync(e, "2 - cfi");
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void GroupBy11()
+        public async Task GroupBy11()
         {
             var xs = AsyncEnumerable.Range(0, 10);
             var ys = xs.GroupBy(x => x % 3, (k, cs) => k + " - " + cs.Aggregate("", (a, c) => a + c).Result);
 
             var e = ys.GetAsyncEnumerator();
-            HasNext(e, "0 - 0369");
-            HasNext(e, "1 - 147");
-            HasNext(e, "2 - 258");
-            NoNext(e);
+            await HasNextAsync(e, "0 - 0369");
+            await HasNextAsync(e, "1 - 147");
+            await HasNextAsync(e, "2 - 258");
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void GroupBy12()
+        public async Task GroupBy12()
         {
             var xs = AsyncEnumerable.Range(0, 10);
             var ys = xs.GroupBy(x => x, new EqMod(3));
 
             var e = ys.GetAsyncEnumerator();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g1 = e.Current;
             Assert.Equal(0, g1.Key);
             var g1e = g1.GetAsyncEnumerator();
-            HasNext(g1e, 0);
-            HasNext(g1e, 3);
-            HasNext(g1e, 6);
-            HasNext(g1e, 9);
-            NoNext(g1e);
+            await HasNextAsync(g1e, 0);
+            await HasNextAsync(g1e, 3);
+            await HasNextAsync(g1e, 6);
+            await HasNextAsync(g1e, 9);
+            await NoNextAsync(g1e);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g2 = e.Current;
             Assert.Equal(1, g2.Key);
             var g2e = g2.GetAsyncEnumerator();
-            HasNext(g2e, 1);
-            HasNext(g2e, 4);
-            HasNext(g2e, 7);
-            NoNext(g2e);
+            await HasNextAsync(g2e, 1);
+            await HasNextAsync(g2e, 4);
+            await HasNextAsync(g2e, 7);
+            await NoNextAsync(g2e);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g3 = e.Current;
             Assert.Equal(2, g3.Key);
             var g3e = g3.GetAsyncEnumerator();
-            HasNext(g3e, 2);
-            HasNext(g3e, 5);
-            HasNext(g3e, 8);
-            NoNext(g3e);
+            await HasNextAsync(g3e, 2);
+            await HasNextAsync(g3e, 5);
+            await HasNextAsync(g3e, 8);
+            await NoNextAsync(g3e);
 
-            NoNext(e);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void GroupBy13()
+        public async Task GroupBy13()
         {
             var xs = AsyncEnumerable.Range(0, 10);
             var ys = xs.GroupBy(x => x, x => (char)('a' + x), new EqMod(3));
 
             var e = ys.GetAsyncEnumerator();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g1 = e.Current;
             Assert.Equal(0, g1.Key);
             var g1e = g1.GetAsyncEnumerator();
-            HasNext(g1e, 'a');
-            HasNext(g1e, 'd');
-            HasNext(g1e, 'g');
-            HasNext(g1e, 'j');
-            NoNext(g1e);
+            await HasNextAsync(g1e, 'a');
+            await HasNextAsync(g1e, 'd');
+            await HasNextAsync(g1e, 'g');
+            await HasNextAsync(g1e, 'j');
+            await NoNextAsync(g1e);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g2 = e.Current;
             Assert.Equal(1, g2.Key);
             var g2e = g2.GetAsyncEnumerator();
-            HasNext(g2e, 'b');
-            HasNext(g2e, 'e');
-            HasNext(g2e, 'h');
-            NoNext(g2e);
+            await HasNextAsync(g2e, 'b');
+            await HasNextAsync(g2e, 'e');
+            await HasNextAsync(g2e, 'h');
+            await NoNextAsync(g2e);
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g3 = e.Current;
             Assert.Equal(2, g3.Key);
             var g3e = g3.GetAsyncEnumerator();
-            HasNext(g3e, 'c');
-            HasNext(g3e, 'f');
-            HasNext(g3e, 'i');
-            NoNext(g3e);
+            await HasNextAsync(g3e, 'c');
+            await HasNextAsync(g3e, 'f');
+            await HasNextAsync(g3e, 'i');
+            await NoNextAsync(g3e);
 
-            NoNext(e);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void GroupBy14()
+        public async Task GroupBy14()
         {
             var xs = AsyncEnumerable.Range(0, 10);
             var ys = xs.GroupBy(x => x, x => (char)('a' + x), (k, cs) => k + " - " + cs.Aggregate("", (a, c) => a + c).Result, new EqMod(3));
 
             var e = ys.GetAsyncEnumerator();
-            HasNext(e, "0 - adgj");
-            HasNext(e, "1 - beh");
-            HasNext(e, "2 - cfi");
-            NoNext(e);
+            await HasNextAsync(e, "0 - adgj");
+            await HasNextAsync(e, "1 - beh");
+            await HasNextAsync(e, "2 - cfi");
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void GroupBy15()
+        public async Task GroupBy15()
         {
             var xs = AsyncEnumerable.Range(0, 10);
             var ys = xs.GroupBy(x => x, (k, cs) => k + " - " + cs.Aggregate("", (a, c) => a + c).Result, new EqMod(3));
 
             var e = ys.GetAsyncEnumerator();
-            HasNext(e, "0 - 0369");
-            HasNext(e, "1 - 147");
-            HasNext(e, "2 - 258");
-            NoNext(e);
+            await HasNextAsync(e, "0 - 0369");
+            await HasNextAsync(e, "1 - 147");
+            await HasNextAsync(e, "2 - 258");
+            await NoNextAsync(e);
         }
 
         [Fact]
@@ -449,38 +406,38 @@ namespace Tests
 
             var e = ys.GetAsyncEnumerator();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g1 = e.Current;
             Assert.Equal(0, g1.Key);
             var g1e = g1.GetAsyncEnumerator();
-            HasNext(g1e, 'a');
-            HasNext(g1e, 'd');
-            HasNext(g1e, 'g');
-            HasNext(g1e, 'j');
-            NoNext(g1e);
+            await HasNextAsync(g1e, 'a');
+            await HasNextAsync(g1e, 'd');
+            await HasNextAsync(g1e, 'g');
+            await HasNextAsync(g1e, 'j');
+            await NoNextAsync(g1e);
             await g1e.DisposeAsync();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g2 = e.Current;
             Assert.Equal(1, g2.Key);
             var g2e = g2.GetAsyncEnumerator();
-            HasNext(g2e, 'b');
-            HasNext(g2e, 'e');
-            HasNext(g2e, 'h');
-            NoNext(g2e);
+            await HasNextAsync(g2e, 'b');
+            await HasNextAsync(g2e, 'e');
+            await HasNextAsync(g2e, 'h');
+            await NoNextAsync(g2e);
             await g2e.DisposeAsync();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g3 = e.Current;
             Assert.Equal(2, g3.Key);
             var g3e = g3.GetAsyncEnumerator();
-            HasNext(g3e, 'c');
-            HasNext(g3e, 'f');
-            HasNext(g3e, 'i');
-            NoNext(g3e);
+            await HasNextAsync(g3e, 'c');
+            await HasNextAsync(g3e, 'f');
+            await HasNextAsync(g3e, 'i');
+            await NoNextAsync(g3e);
             await g3e.DisposeAsync();
 
-            NoNext(e);
+            await NoNextAsync(e);
 
             await e.DisposeAsync();
         }
@@ -494,7 +451,7 @@ namespace Tests
             var e = ys.GetAsyncEnumerator();
             await e.DisposeAsync();
 
-            Assert.False(e.MoveNextAsync().Result);
+            Assert.False(await e.MoveNextAsync());
         }
 
         [Fact]
@@ -505,21 +462,21 @@ namespace Tests
 
             var e = ys.GetAsyncEnumerator();
 
-            Assert.True(e.MoveNextAsync().Result);
+            Assert.True(await e.MoveNextAsync());
             var g1 = e.Current;
             Assert.Equal(0, g1.Key);
             var g1e = g1.GetAsyncEnumerator();
-            HasNext(g1e, 'a');
+            await HasNextAsync(g1e, 'a');
 
             await e.DisposeAsync();
 
-            HasNext(g1e, 'd');
-            HasNext(g1e, 'g');
-            HasNext(g1e, 'j');
-            NoNext(g1e);
+            await HasNextAsync(g1e, 'd');
+            await HasNextAsync(g1e, 'g');
+            await HasNextAsync(g1e, 'j');
+            await NoNextAsync(g1e);
             await g1e.DisposeAsync();
 
-            Assert.False(e.MoveNextAsync().Result);
+            Assert.False(await e.MoveNextAsync());
         }
 
         [Fact]

+ 33 - 33
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupJoin.cs

@@ -5,6 +5,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 using Xunit;
 
 namespace Tests
@@ -14,22 +15,21 @@ namespace Tests
         [Fact]
         public void GroupJoin_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(default, Return42, x => x, x => x, (x, y) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, default, x => x, x => x, (x, y) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, Return42, default, x => x, (x, y) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, Return42, x => x, default, (x, y) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, Return42, x => x, x => x, default));
-
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(default, Return42, x => x, x => x, (x, y) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, default, x => x, x => x, (x, y) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, Return42, default, x => x, (x, y) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, Return42, x => x, default, (x, y) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, Return42, x => x, x => x, default, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, Return42, x => x, x => x, (x, y) => x, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(default, Return42, x => x, x => x, (x, y) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, default, x => x, x => x, (x, y) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupJoin(Return42, Return42, default, x => x, (x, y) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupJoin(Return42, Return42, x => x, default, (x, y) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, Return42, x => x, x => x, default));
+
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(default, Return42, x => x, x => x, (x, y) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, default, x => x, x => x, (x, y) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupJoin(Return42, Return42, default, x => x, (x, y) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupJoin(Return42, Return42, x => x, default, (x, y) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupJoin<int, int, int, int>(Return42, Return42, x => x, x => x, default, EqualityComparer<int>.Default));
         }
 
         [Fact]
-        public void GroupJoin1()
+        public async Task GroupJoin1()
         {
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
             var ys = new[] { 4, 7, 6, 2, 3, 4, 8, 9 }.ToAsyncEnumerable();
@@ -37,14 +37,14 @@ namespace Tests
             var res = xs.GroupJoin(ys, x => x % 3, y => y % 3, (x, i) => x + " - " + i.Aggregate("", (s, j) => s + j).Result);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, "0 - 639");
-            HasNext(e, "1 - 474");
-            HasNext(e, "2 - 28");
-            NoNext(e);
+            await HasNextAsync(e, "0 - 639");
+            await HasNextAsync(e, "1 - 474");
+            await HasNextAsync(e, "2 - 28");
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void GroupJoin2()
+        public async Task GroupJoin2()
         {
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
             var ys = new[] { 3, 6, 4 }.ToAsyncEnumerable();
@@ -52,14 +52,14 @@ namespace Tests
             var res = xs.GroupJoin(ys, x => x % 3, y => y % 3, (x, i) => x + " - " + i.Aggregate("", (s, j) => s + j).Result);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, "0 - 36");
-            HasNext(e, "1 - 4");
-            HasNext(e, "2 - ");
-            NoNext(e);
+            await HasNextAsync(e, "0 - 36");
+            await HasNextAsync(e, "1 - 4");
+            await HasNextAsync(e, "2 - ");
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void GroupJoin3()
+        public async Task GroupJoin3Async()
         {
             var ex = new Exception("Bang!");
             var xs = Throw<int>(ex);
@@ -68,11 +68,11 @@ namespace Tests
             var res = xs.GroupJoin(ys, x => x % 3, y => y % 3, (x, i) => x + " - " + i.Aggregate("", (s, j) => s + j).Result);
 
             var e = res.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void GroupJoin4()
+        public async Task GroupJoin4Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
@@ -81,11 +81,11 @@ namespace Tests
             var res = xs.GroupJoin(ys, x => x % 3, y => y % 3, (x, i) => x + " - " + i.Aggregate("", (s, j) => s + j).Result);
 
             var e = res.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void GroupJoin5()
+        public async Task GroupJoin5Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
@@ -94,11 +94,11 @@ namespace Tests
             var res = xs.GroupJoin(ys, x => { throw ex; }, y => y % 3, (x, i) => x + " - " + i.Aggregate("", (s, j) => s + j).Result);
 
             var e = res.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void GroupJoin6()
+        public async Task GroupJoin6Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
@@ -107,11 +107,11 @@ namespace Tests
             var res = xs.GroupJoin(ys, x => x % 3, y => { throw ex; }, (x, i) => x + " - " + i.Aggregate("", (s, j) => s + j).Result);
 
             var e = res.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void GroupJoin7()
+        public async Task GroupJoin7()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
@@ -125,8 +125,8 @@ namespace Tests
             });
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, "0 - 36");
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await HasNextAsync(e, "0 - 36");
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
     }
 }

+ 12 - 13
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Intersect.cs

@@ -15,38 +15,37 @@ namespace Tests
         [Fact]
         public void Intersect_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Intersect<int>(default, Return42));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Intersect<int>(Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Intersect(default, Return42));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Intersect(Return42, default));
 
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Intersect<int>(default, Return42, new Eq()));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Intersect<int>(Return42, default, new Eq()));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Intersect<int>(Return42, Return42, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Intersect(default, Return42, new Eq()));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Intersect(Return42, default, new Eq()));
         }
 
         [Fact]
-        public void Intersect1()
+        public async Task Intersect1()
         {
             var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
             var ys = new[] { 3, 5, 1, 4 }.ToAsyncEnumerable();
             var res = xs.Intersect(ys);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, 3);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, 3);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Intersect2()
+        public async Task Intersect2()
         {
             var xs = new[] { 1, 2, -3 }.ToAsyncEnumerable();
             var ys = new[] { 3, 5, -1, 4 }.ToAsyncEnumerable();
             var res = xs.Intersect(ys, new Eq());
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 1);
-            HasNext(e, -3);
-            NoNext(e);
+            await HasNextAsync(e, 1);
+            await HasNextAsync(e, -3);
+            await NoNextAsync(e);
         }
 
         [Fact]

+ 55 - 56
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Join.cs

@@ -15,22 +15,21 @@ namespace Tests
         [Fact]
         public void Join_Null()
         {
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(default, Return42, x => x, x => x, (x, y) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, default, x => x, x => x, (x, y) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, Return42, default, x => x, (x, y) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, Return42, x => x, default, (x, y) => x));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, Return42, x => x, x => x, default));
-
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(default, Return42, x => x, x => x, (x, y) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, default, x => x, x => x, (x, y) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, Return42, default, x => x, (x, y) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, Return42, x => x, default, (x, y) => x, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, Return42, x => x, x => x, default, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, Return42, x => x, x => x, (x, y) => x, default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(default, Return42, x => x, x => x, (x, y) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, default, x => x, x => x, (x, y) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Join(Return42, Return42, default, x => x, (x, y) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Join(Return42, Return42, x => x, default, (x, y) => x));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, Return42, x => x, x => x, default));
+
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(default, Return42, x => x, x => x, (x, y) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, default, x => x, x => x, (x, y) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Join(Return42, Return42, default, x => x, (x, y) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Join(Return42, Return42, x => x, default, (x, y) => x, EqualityComparer<int>.Default));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Join<int, int, int, int>(Return42, Return42, x => x, x => x, default, EqualityComparer<int>.Default));
         }
 
         [Fact]
-        public void Join1()
+        public async Task Join1()
         {
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
             var ys = new[] { 3, 6, 4 }.ToAsyncEnumerable();
@@ -38,14 +37,14 @@ namespace Tests
             var res = xs.Join(ys, x => x % 3, y => y % 3, (x, y) => x + y);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 0 + 3);
-            HasNext(e, 0 + 6);
-            HasNext(e, 1 + 4);
-            NoNext(e);
+            await HasNextAsync(e, 0 + 3);
+            await HasNextAsync(e, 0 + 6);
+            await HasNextAsync(e, 1 + 4);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Join2()
+        public async Task Join2()
         {
             var xs = new[] { 3, 6, 4 }.ToAsyncEnumerable();
             var ys = new[] { 0, 1, 2 }.ToAsyncEnumerable();
@@ -53,14 +52,14 @@ namespace Tests
             var res = xs.Join(ys, x => x % 3, y => y % 3, (x, y) => x + y);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 3 + 0);
-            HasNext(e, 6 + 0);
-            HasNext(e, 4 + 1);
-            NoNext(e);
+            await HasNextAsync(e, 3 + 0);
+            await HasNextAsync(e, 6 + 0);
+            await HasNextAsync(e, 4 + 1);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Join3()
+        public async Task Join3()
         {
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
             var ys = new[] { 3, 6 }.ToAsyncEnumerable();
@@ -68,13 +67,13 @@ namespace Tests
             var res = xs.Join(ys, x => x % 3, y => y % 3, (x, y) => x + y);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 0 + 3);
-            HasNext(e, 0 + 6);
-            NoNext(e);
+            await HasNextAsync(e, 0 + 3);
+            await HasNextAsync(e, 0 + 6);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Join4()
+        public async Task Join4()
         {
             var xs = new[] { 3, 6 }.ToAsyncEnumerable();
             var ys = new[] { 0, 1, 2 }.ToAsyncEnumerable();
@@ -82,13 +81,13 @@ namespace Tests
             var res = xs.Join(ys, x => x % 3, y => y % 3, (x, y) => x + y);
 
             var e = res.GetAsyncEnumerator();
-            HasNext(e, 3 + 0);
-            HasNext(e, 6 + 0);
-            NoNext(e);
+            await HasNextAsync(e, 3 + 0);
+            await HasNextAsync(e, 6 + 0);
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Join5()
+        public async Task Join5Async()
         {
             var ex = new Exception("Bang!");
             var xs = Throw<int>(ex);
@@ -97,11 +96,11 @@ namespace Tests
             var res = xs.Join(ys, x => x % 3, y => y % 3, (x, y) => x + y);
 
             var e = res.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Join6()
+        public async Task Join6Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
@@ -110,11 +109,11 @@ namespace Tests
             var res = xs.Join(ys, x => x % 3, y => y % 3, (x, y) => x + y);
 
             var e = res.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Join7()
+        public async Task Join7Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
@@ -123,11 +122,11 @@ namespace Tests
             var res = xs.Join(ys, x => { throw ex; }, y => y, (x, y) => x + y);
 
             var e = res.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Join8()
+        public async Task Join8Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
@@ -136,11 +135,11 @@ namespace Tests
             var res = xs.Join(ys, x => x, y => { throw ex; }, (x, y) => x + y);
 
             var e = res.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
-        public void Join9()
+        public async Task Join9Async()
         {
             var ex = new Exception("Bang!");
             var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
@@ -149,7 +148,7 @@ namespace Tests
             var res = xs.Join<int, int, int, int>(ys, x => x, y => y, (x, y) => { throw ex; });
 
             var e = res.GetAsyncEnumerator();
-            AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), SingleInnerExceptionMatches(ex));
+            await AssertThrowsAsync(e.MoveNextAsync(), ex);
         }
 
         [Fact]
@@ -164,7 +163,7 @@ namespace Tests
         }
 
         [Fact]
-        public void Join11()
+        public async Task Join11()
         {
             var customers = new List<Customer>
             {
@@ -188,17 +187,17 @@ namespace Tests
                                             (c, o) => new CustomerOrder { CustomerId = c.CustomerId, OrderId = o.OrderId });
 
             var e = asyncResult.GetAsyncEnumerator();
-            HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 1 });
-            HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 2 });
-            HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 3 });
-            HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 4 });
-            HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 5 });
-            HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 6 });
-            NoNext(e);
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 1 });
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 2 });
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 3 });
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 4 });
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 5 });
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 6 });
+            await NoNextAsync(e);
         }
 
         [Fact]
-        public void Join12()
+        public async Task Join12()
         {
             var customers = new List<Customer>
             {
@@ -221,13 +220,13 @@ namespace Tests
                                             (c, o) => new CustomerOrder { CustomerId = c.CustomerId, OrderId = o.OrderId });
 
             var e = asyncResult.GetAsyncEnumerator();
-            HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 1 });
-            HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 2 });
-            HasNext(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 3 });
-            HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 4 });
-            HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 5 });
-            HasNext(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 6 });
-            NoNext(e);
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 1 });
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 2 });
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "ALFKI", OrderId = 3 });
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 4 });
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 5 });
+            await HasNextAsync(e, new CustomerOrder { CustomerId = "FISSA", OrderId = 6 });
+            await NoNextAsync(e);
         }
 
         public class Customer

+ 20 - 21
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Last.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -18,76 +17,76 @@ namespace Tests
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Last<int>(default));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Last<int>(default, x => true));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Last<int>(Return42, default(Func<int, bool>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Last(Return42, default(Func<int, bool>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Last<int>(default, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Last<int>(default, x => true, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Last<int>(Return42, default(Func<int, bool>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.Last(Return42, default(Func<int, bool>), CancellationToken.None));
         }
 
         [Fact]
-        public void Last1()
+        public async Task Last1Async()
         {
             var res = AsyncEnumerable.Empty<int>().Last();
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await AssertThrowsAsync<InvalidOperationException>(res);
         }
 
         [Fact]
-        public void Last2()
+        public async Task Last2Async()
         {
             var res = AsyncEnumerable.Empty<int>().Last(x => true);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await AssertThrowsAsync<InvalidOperationException>(res);
         }
 
         [Fact]
-        public void Last3()
+        public async Task Last3Async()
         {
             var res = Return42.Last(x => x % 2 != 0);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
+            await AssertThrowsAsync<InvalidOperationException>(res);
         }
 
         [Fact]
-        public void Last4()
+        public async Task Last4Async()
         {
             var res = Return42.Last();
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void Last5()
+        public async Task Last5Async()
         {
             var res = Return42.Last(x => x % 2 == 0);
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void Last6()
+        public async Task Last6Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).Last();
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void Last7()
+        public async Task Last7Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).Last(x => true);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void Last8()
+        public async Task Last8Async()
         {
             var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().Last();
-            Assert.Equal(90, res.Result);
+            Assert.Equal(90, await res);
         }
 
         [Fact]
-        public void Last9()
+        public async Task Last9Async()
         {
             var res = new[] { 42, 23, 45, 90 }.ToAsyncEnumerable().Last(x => x % 2 != 0);
-            Assert.Equal(45, res.Result);
+            Assert.Equal(45, await res);
         }
     }
 }

+ 22 - 23
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/LastOrDefault.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -18,83 +17,83 @@ namespace Tests
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LastOrDefault<int>(default));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LastOrDefault<int>(default, x => true));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LastOrDefault<int>(Return42, default(Func<int, bool>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LastOrDefault(Return42, default(Func<int, bool>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LastOrDefault<int>(default, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LastOrDefault<int>(default, x => true, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LastOrDefault<int>(Return42, default(Func<int, bool>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LastOrDefault(Return42, default(Func<int, bool>), CancellationToken.None));
         }
 
         [Fact]
-        public void LastOrDefault1()
+        public async Task LastOrDefault1Async()
         {
             var res = AsyncEnumerable.Empty<int>().LastOrDefault();
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
         }
 
         [Fact]
-        public void LastOrDefault2()
+        public async Task LastOrDefault2Async()
         {
             var res = AsyncEnumerable.Empty<int>().LastOrDefault(x => true);
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
         }
 
         [Fact]
-        public void LastOrDefault3()
+        public async Task LastOrDefault3Async()
         {
             var res = Return42.LastOrDefault(x => x % 2 != 0);
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
         }
 
         [Fact]
-        public void LastOrDefault4()
+        public async Task LastOrDefault4Async()
         {
             var res = Return42.LastOrDefault();
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void LastOrDefault5()
+        public async Task LastOrDefault5Async()
         {
             var res = Return42.LastOrDefault(x => x % 2 == 0);
-            Assert.Equal(42, res.Result);
+            Assert.Equal(42, await res);
         }
 
         [Fact]
-        public void LastOrDefault6()
+        public async Task LastOrDefault6Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).LastOrDefault();
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void LastOrDefault7()
+        public async Task LastOrDefault7Async()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).LastOrDefault(x => true);
-            AssertThrows<Exception>(() => res.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(res, ex);
         }
 
         [Fact]
-        public void LastOrDefault8()
+        public async Task LastOrDefault8Async()
         {
             var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().LastOrDefault();
-            Assert.Equal(90, res.Result);
+            Assert.Equal(90, await res);
         }
 
         [Fact]
-        public void LastOrDefault9()
+        public async Task LastOrDefault9Async()
         {
             var res = new[] { 42, 23, 45, 90 }.ToAsyncEnumerable().LastOrDefault(x => x % 2 != 0);
-            Assert.Equal(45, res.Result);
+            Assert.Equal(45, await res);
         }
 
         [Fact]
-        public void LastOrDefault10()
+        public async Task LastOrDefault10Async()
         {
             var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().LastOrDefault(x => x < 10);
-            Assert.Equal(0, res.Result);
+            Assert.Equal(0, await res);
         }
     }
 }

+ 24 - 13
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/LongCount.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -18,35 +17,47 @@ namespace Tests
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LongCount<int>(default));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LongCount<int>(default, x => true));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LongCount<int>(Return42, default(Func<int, bool>)));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LongCount(Return42, default(Func<int, bool>)));
 
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LongCount<int>(default, CancellationToken.None));
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LongCount<int>(default, x => true, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LongCount<int>(Return42, default(Func<int, bool>), CancellationToken.None));
+            await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.LongCount(Return42, default(Func<int, bool>), CancellationToken.None));
         }
 
         [Fact]
-        public void LongCount1()
+        public async Task LongCount1()
         {
-            Assert.Equal(0, new int[0].ToAsyncEnumerable().LongCount().Result);
-            Assert.Equal(3, new[] { 1, 2, 3 }.ToAsyncEnumerable().LongCount().Result);
-            AssertThrows<AggregateException>(() => Throw<int>(new Exception("Bang!")).LongCount().Wait(WaitTimeoutMs));
+            Assert.Equal(0, await new int[0].ToAsyncEnumerable().LongCount());
+            Assert.Equal(3, await new[] { 1, 2, 3 }.ToAsyncEnumerable().LongCount());
         }
 
         [Fact]
-        public void LongCount2()
+        public async Task LongCount2()
         {
-            Assert.Equal(0, new int[0].ToAsyncEnumerable().LongCount(x => x < 3).Result);
-            Assert.Equal(2, new[] { 1, 2, 3 }.ToAsyncEnumerable().LongCount(x => x < 3).Result);
-            AssertThrows<AggregateException>(() => Throw<int>(new Exception("Bang!")).LongCount(x => x < 3).Wait(WaitTimeoutMs));
+            Assert.Equal(0, await new int[0].ToAsyncEnumerable().LongCount(x => x < 3));
+            Assert.Equal(2, await new[] { 1, 2, 3 }.ToAsyncEnumerable().LongCount(x => x < 3));
         }
 
         [Fact]
-        public void LongCount3()
+        public async Task LongCount3Async()
         {
             var ex = new Exception("Bang!");
             var ys = new[] { 1, 2, 3 }.ToAsyncEnumerable().LongCount(new Func<int, bool>(x => { throw ex; }));
-            AssertThrows<Exception>(() => ys.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
+            await AssertThrowsAsync(ys, ex);
+        }
+
+        [Fact]
+        public async Task LongCount4Async()
+        {
+            var ex = new Exception("Bang!");
+            await AssertThrowsAsync(Throw<int>(ex).LongCount(), ex);
+        }
+
+        [Fact]
+        public async Task LongCount5Async()
+        {
+            var ex = new Exception("Bang!");
+            await AssertThrowsAsync(Throw<int>(ex).LongCount(x => x < 3), ex);
         }
     }
 }

+ 33 - 33
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Max.cs

@@ -92,102 +92,102 @@ namespace Tests
         }
 
         [Fact]
-        public void Max1()
+        public async Task Max1Async()
         {
             var xs = new[] { 2, 7, 3 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
 
         [Fact]
-        public void Max2()
+        public async Task Max2Async()
         {
             var xs = new[] { 2, default(int?), 3, 1 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
 
         [Fact]
-        public void Max3()
+        public async Task Max3Async()
         {
             var xs = new[] { 2L, 7L, 3L };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
 
         [Fact]
-        public void Max4()
+        public async Task Max4Async()
         {
             var xs = new[] { 2L, default(long?), 3L, 1L };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
 
         [Fact]
-        public void Max5()
+        public async Task Max5Async()
         {
             var xs = new[] { 2.0, 7.0, 3.0 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
 
         [Fact]
-        public void Max6()
+        public async Task Max6Async()
         {
             var xs = new[] { 2.0, default(double?), 3.0, 1.0 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
 
         [Fact]
-        public void Max7()
+        public async Task Max7Async()
         {
             var xs = new[] { 2.0f, 7.0f, 3.0f };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
 
         [Fact]
-        public void Max8()
+        public async Task Max8Async()
         {
             var xs = new[] { 2.0f, default(float?), 3.0f, 1.0f };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
 
         [Fact]
-        public void Max9()
+        public async Task Max9Async()
         {
             var xs = new[] { 2.0m, 7.0m, 3.0m };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
 
         [Fact]
-        public void Max10()
+        public async Task Max10Async()
         {
             var xs = new[] { 2.0m, default(decimal?), 3.0m, 1.0m };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
 
         [Fact]
-        public void Max11()
+        public async Task Max11Async()
         {
             var xs = new[] { DateTime.Now.AddDays(1), DateTime.Now.Subtract(TimeSpan.FromDays(1)), DateTime.Now.AddDays(2), DateTime.Now };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Max(), ys.Max().Result);
-            Assert.Equal(xs.Max(), ys.Max(x => x).Result);
+            Assert.Equal(xs.Max(), await ys.Max());
+            Assert.Equal(xs.Max(), await ys.Max(x => x));
         }
     }
 }

+ 33 - 33
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Min.cs

@@ -92,102 +92,102 @@ namespace Tests
         }
 
         [Fact]
-        public void Min1()
+        public async Task Min1Async()
         {
             var xs = new[] { 2, 1, 3 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
 
         [Fact]
-        public void Min2()
+        public async Task Min2Async()
         {
             var xs = new[] { 2, default(int?), 3 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
 
         [Fact]
-        public void Min3()
+        public async Task Min3Async()
         {
             var xs = new[] { 2L, 1L, 3L };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
 
         [Fact]
-        public void Min4()
+        public async Task Min4Async()
         {
             var xs = new[] { 2L, default(long?), 3L };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
 
         [Fact]
-        public void Min5()
+        public async Task Min5Async()
         {
             var xs = new[] { 2.0, 1.0, 3.0 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
 
         [Fact]
-        public void Min6()
+        public async Task Min6Async()
         {
             var xs = new[] { 2.0, default(double?), 3.0 };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
 
         [Fact]
-        public void Min7()
+        public async Task Min7Async()
         {
             var xs = new[] { 2.0f, 1.0f, 3.0f };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
 
         [Fact]
-        public void Min8()
+        public async Task Min8Async()
         {
             var xs = new[] { 2.0f, default(float?), 3.0f };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
 
         [Fact]
-        public void Min9()
+        public async Task Min9Async()
         {
             var xs = new[] { 2.0m, 1.0m, 3.0m };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
 
         [Fact]
-        public void Min10()
+        public async Task Min10Async()
         {
             var xs = new[] { 2.0m, default(decimal?), 3.0m };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
 
         [Fact]
-        public void Min11()
+        public async Task Min11Async()
         {
             var xs = new[] { DateTime.Now.AddDays(1), DateTime.Now.Subtract(TimeSpan.FromDays(1)), DateTime.Now.AddDays(2), DateTime.Now };
             var ys = xs.ToAsyncEnumerable();
-            Assert.Equal(xs.Min(), ys.Min().Result);
-            Assert.Equal(xs.Min(), ys.Min(x => x).Result);
+            Assert.Equal(xs.Min(), await ys.Min());
+            Assert.Equal(xs.Min(), await ys.Min(x => x));
         }
     }
 }

Some files were not shown because too many files changed in this diff