public static IEnumerableAsync <Tuple <T1, T2> > Zip <T1, T2>(this IEnumerableAsync <T1> input1, IEnumerableAsync <T2> input2) { return(Produce <Tuple <T1, T2> >(async yieldAsync => { IEnumeratorAsync <T1> enum1 = NullEnumerator <T1> .Instance; IEnumeratorAsync <T2> enum2 = NullEnumerator <T2> .Instance; await TryFinallyAsync( async() => { enum1 = await input1.GetEnumerator(); enum2 = await input2.GetEnumerator(); while (AllTrue(await Task.WhenAll(enum1.MoveNext(), enum2.MoveNext()))) { await yieldAsync.YieldAsync(Tuple.Create(enum1.Current, enum2.Current)); } return 0; }, () => Task.WhenAll(enum1.Dispose(), enum2.Dispose()) ); })); }
async Task <bool> EnumeratorMoved() { await open.Task; bool result; var enumeratorMovedRef = enumeratorMoved; if (Interlocked.Decrement(ref awaitedEnumerators) == 0) { result = await enumerator.MoveNext(); awaitedEnumerators = totalEnumerators; enumeratorMoved = new TaskCompletionSource <bool>(); enumeratorMovedRef.SetResult(result); } else { result = await enumeratorMovedRef.Task; } await Task.Yield(); return(result); }