using System.Diagnostics;
using System.Threading.Tasks;
using System.Collections.Generic;
public static async Task Main()
var stopwatch = Stopwatch.StartNew();
await foreach (var pair in Zip(First(), Second()))
Console.WriteLine($"Duration: {stopwatch.ElapsedMilliseconds:#,0} msec");
static async IAsyncEnumerable<int> First()
for (int i = 1; i <= 5; i++) { await Task.Delay(100); yield return i; }
static async IAsyncEnumerable<int> Second()
for (int i = 1; i <= 5; i++) { await Task.Delay(100); yield return i; }
public static async IAsyncEnumerable<(TFirst, TSecond)> Zip<TFirst, TSecond>(IAsyncEnumerable<TFirst> first, IAsyncEnumerable<TSecond> second)
await using var e1 = first.GetAsyncEnumerator();
await using var e2 = second.GetAsyncEnumerator();
var t1 = e1.MoveNextAsync().AsTask();
var t2 = e2.MoveNextAsync().AsTask();
await Task.WhenAll(t1, t2);
if (!t1.Result || !t2.Result)
yield return (e1.Current, e2.Current);