.NET Fiddle

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
					
public static class Program
{
	// Was having issues with the NuGet package so wrote a custom Range function instead, at the bottom
	
	public static async Task Main()
	{
		var sequence_A = Range("A{0}", 1, 5);
		var sequence_B = Range("B{0}", 1, 3);
		var sequence_C = Range("C{0}", 1, 7);
		var merged = Interleave(sequence_A, sequence_B, sequence_C);
		await foreach (var item in merged) Console.WriteLine(item);
	}
	
	public static IAsyncEnumerable<T> Interleave<T>(params IAsyncEnumerable<T>[] sources) =>
		Interleave(default, sources);
	
	public static async IAsyncEnumerable<T> Interleave<T>([EnumeratorCancellation] CancellationToken token, IAsyncEnumerable<T>[] sources)
	{
		if(sources.Length == 0)
			yield break;
		var enumerators = new List<IAsyncEnumerator<T>>(sources.Length);
		try
		{
			for(var i = 0; i < sources.Length; i++)
				enumerators.Add(sources[i].GetAsyncEnumerator(token));

			var j = 0;
			do
			{
				if(await enumerators[j].MoveNextAsync())
				{
					yield return enumerators[j].Current;
					j++;
					if(j >= enumerators.Count)
						j = 0;
				}
				else
				{
					try
					{
						await enumerators[j].DisposeAsync();
					}
					catch
					{ //
					}
					enumerators.RemoveAt(j);
				}
			} while (enumerators.Count > 0);
		}
		finally
		{
			for(var i = 0; i < enumerators.Count; i++)
			{
				try
				{
					await enumerators[i].DisposeAsync();
				}
				catch
				{ //
				}
			}
		}
	}
	
	static async IAsyncEnumerable<string> Range(string text, int start, int count) {
		for (int i = 0; i < count; i++)
			yield return string.Format(text, start + i);
	}
}
;