浏览代码

Adding tests for OrderBy.

Bart De Smet 6 年之前
父节点
当前提交
a5ad50d29b

+ 14 - 0
Ix.NET/Source/System.Linq.Async.Tests/System.Linq.Async.Tests.csproj

@@ -25,6 +25,11 @@
       <AutoGen>True</AutoGen>
       <DependentUpon>MinMax.Generated.tt</DependentUpon>
     </None>
+    <None Include="System\Linq\Operators\OrderBy.Generated.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>OrderBy.Generated.tt</DependentUpon>
+    </None>
   </ItemGroup>
 
   <ItemGroup>
@@ -48,6 +53,10 @@
       <Generator>TextTemplatingFileGenerator</Generator>
       <LastGenOutput>MinMax.Generated.cs</LastGenOutput>
     </None>
+    <None Update="System\Linq\Operators\OrderBy.Generated.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>OrderBy.Generated.cs</LastGenOutput>
+    </None>
   </ItemGroup>
 
   <ItemGroup>
@@ -65,6 +74,11 @@
       <AutoGen>True</AutoGen>
       <DependentUpon>MinMax.Generated.tt</DependentUpon>
     </Compile>
+    <Compile Update="System\Linq\Operators\OrderBy.Generated.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>OrderBy.Generated.tt</DependentUpon>
+    </Compile>
   </ItemGroup>
 
 </Project>

+ 5950 - 0
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/OrderBy.Generated.cs

@@ -0,0 +1,5950 @@
+// 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;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Tests
+{
+    partial class OrderBy
+    {
+        [Fact]
+        public async Task OrderBy_OrderBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2);
+            var syncRes = xs.OrderBy(x => x % 2);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2));
+            var syncRes = xs.OrderBy(x => x % 2);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2));
+            var syncRes = xs.OrderBy(x => x % 2);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2);
+            var syncRes = xs.OrderByDescending(x => x % 2);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2));
+            var syncRes = xs.OrderByDescending(x => x % 2);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2));
+            var syncRes = xs.OrderByDescending(x => x % 2);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => x % 3);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => x % 3);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => x % 3);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => x % 3);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenBy_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenBy_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenBy_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenBy_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenBy_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenBy_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescending_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescending_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescending_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescending_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescending_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescending_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderBy_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenBy_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenBy_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenBy_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenBy_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenBy_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenBy_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescending_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescending_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescending_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescending_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescending_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescending_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsync_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenBy_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenBy_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenBy_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenBy_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenBy_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenBy_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescending_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescending_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescending_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescending_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescending_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescending_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderBy((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderBy(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenBy_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenBy_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenBy_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenBy_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenBy_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenBy_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescending_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescending_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescending_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescending_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescending_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescending_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescending_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => x % 2).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenBy_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenBy_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenBy_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenBy_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenBy_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenBy_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescending_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescending_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescending_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescending_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescending_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescending_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsync_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending(x => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenBy_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenBy_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenBy_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenBy_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenBy_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenBy_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenBy((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescending_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescending_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescending_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescending_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescending_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescending_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => x % 3).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsync_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsync_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsync_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsync_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsync_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsync_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending(x => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenBy()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenByAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenByAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenBy((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenBy(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenByDescending()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => x % 4);
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsync()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending(x => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+        [Fact]
+        public async Task OrderBy_OrderByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation_ThenByDescendingAsyncWithCancellation()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable().OrderByDescending((x, ct) => new ValueTask<int>(x % 2)).ThenByDescending((x, ct) => new ValueTask<int>(x % 3)).ThenByDescending((x, ct) => new ValueTask<int>(x % 4));
+            var syncRes = xs.OrderByDescending(x => x % 2).ThenByDescending(x => x % 3).ThenByDescending(x => x % 4);
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+    }
+}

+ 133 - 0
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/OrderBy.Generated.tt

@@ -0,0 +1,133 @@
+// 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. 
+
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ import namespace="System.Linq" #>
+<#@ import namespace="System.Text" #>
+<#@ import namespace="System.Collections.Generic" #>
+<#@ output extension=".cs" #>
+<#
+Func<bool, bool, bool, bool, string, string> getAsyncMethod = (then, desc, async, cancel, body) =>
+{
+    var mtd = (then ? "ThenBy" : "OrderBy") + (desc ? "Descending" : "");
+
+    var arg = async ? (cancel ? "(x, ct) => " : "x => ") + "new ValueTask<int>(" + body + ")" : "x => " + body;
+
+    return "." + mtd + "(" + arg + ")";
+};
+
+Func<bool, bool, int, string, string> getAsyncMethodWithVariant = (then, desc, variant, body) =>
+{
+    return getAsyncMethod(then, desc, variant > 0 ? true : false, variant == 2 ? true : false, body);
+};
+
+Func<bool, bool, string, string> getSyncMethod = (then, desc, body) =>
+{
+    var mtd = (then ? "ThenBy" : "OrderBy") + (desc ? "Descending" : "");
+
+    var arg = "x => " + body;
+
+    return "." + mtd + "(" + arg + ")";
+};
+
+Func<bool, bool, int, string> getVariantName = (then, desc, variant) =>
+{
+    var v = variant == 0 ? "" : (variant == 1 ? "Async" : "AsyncWithCancellation");
+    return "_" + (then ? "ThenBy" : "OrderBy") + (desc ? "Descending" : "") + v;
+};
+
+Func<bool, string, List<Tuple<string, string, string>>> getAsyncMethodVariants = (then, body) =>
+{
+    var res = new List<Tuple<string, string, string>>();
+
+    foreach (var desc in new[] { false, true })
+    {
+        foreach (var variant in new[] { 0, 1, 2 })
+        {
+            var v = getVariantName(then, desc, variant);
+            var async = getAsyncMethodWithVariant(then, desc, variant, body);
+            var sync = getSyncMethod(then, desc, body);
+
+            res.Add(new Tuple<string, string, string>(v, async, sync));
+        }
+    }
+
+    return res;
+};
+
+Func<int, List<Tuple<string, string, string>>> getVariants = null;
+
+getVariants = depth =>
+{
+    if (depth == 1)
+    {
+        return getAsyncMethodVariants(false, "x % 2");
+    }
+    else
+    {
+        var res = new List<Tuple<string, string, string>>();
+
+        var next = getVariants(depth - 1);
+
+        foreach (var item in next)
+        {
+            foreach (var variant in getAsyncMethodVariants(true, "x % " + (depth + 1)))
+            {
+                res.Add(new Tuple<string, string, string>(item.Item1 + variant.Item1, item.Item2 + variant.Item2, item.Item3 + variant.Item3));
+            }
+        }
+
+        return res;
+    }
+};
+#>
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Tests
+{
+    partial class OrderBy
+    {
+<#
+for (var i = 1; i <= 3; i++)
+{
+    foreach (var v in getVariants(i))
+    {
+        var variant = v.Item1;
+        var asyncCall = v.Item2;
+        var syncCall = v.Item3;
+#>
+        [Fact]
+        public async Task OrderBy<#=variant#>()
+        {
+            var rand = new Random(42);
+            var xs = Enumerable.Range(0, 100).Select(x => rand.Next(0, 100)).ToArray().Select(x => x);
+
+            var asyncRes = xs.ToAsyncEnumerable()<#=asyncCall#>;
+            var syncRes = xs<#=syncCall#>;
+
+            Assert.True(syncRes.ToList().SequenceEqual(await asyncRes.ToListAsync()));
+            Assert.True(syncRes.ToArray().SequenceEqual(await asyncRes.ToArrayAsync()));
+
+            Assert.Equal(syncRes.Count(), await asyncRes.CountAsync());
+
+            Assert.Equal(syncRes.First(), await asyncRes.FirstAsync());
+            Assert.Equal(syncRes.Last(), await asyncRes.LastAsync());
+
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.Equal(syncRes.ElementAt(i), await asyncRes.ElementAtAsync(i));
+            }
+        }
+
+<#
+    }
+}
+#>
+    }
+}

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

@@ -10,7 +10,7 @@ using Xunit;
 
 namespace Tests
 {
-    public class OrderBy : AsyncEnumerableTests
+    public partial class OrderBy : AsyncEnumerableTests
     {
         [Fact]
         public void OrderBy_Null()

+ 12 - 0
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/OrderBy.cs

@@ -30,6 +30,18 @@ namespace System.Linq
             return new OrderedAsyncEnumerableWithTask<TSource, TKey>(source, keySelector, comparer: null, descending: false, parent: null);
         }
 
+#if !NO_DEEP_CANCELLATION
+        public static IOrderedAsyncEnumerable<TSource> OrderBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector)
+        {
+            if (source == null)
+                throw Error.ArgumentNull(nameof(source));
+            if (keySelector == null)
+                throw Error.ArgumentNull(nameof(keySelector));
+
+            return new OrderedAsyncEnumerableWithTaskAndCancellation<TSource, TKey>(source, keySelector, comparer: null, descending: false, parent: null);
+        }
+#endif
+
         public static IOrderedAsyncEnumerable<TSource> OrderBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
         {
             if (source == null)