簡體   English   中英

如何等待多個 IAsyncEnumerable

[英]How to await multiple IAsyncEnumerable

我們有這樣的代碼:

var intList = new List<int>{1,2,3};
var asyncEnumerables = intList.Select(Foo);

private async IAsyncEnumerable<int> Foo(int a)
{
  while (true)
  {
    await Task.Delay(5000);
    yield return a;
  } 
}

我需要為每個asyncEnumerable的條目啟動await foreach 每次循環迭代都應該相互等待,每次迭代完成后,我需要收集每次迭代的數據並通過另一種方法對其進行處理。

我可以通過 TPL 以某種方式實現嗎? 否則,你不能給我一些想法嗎?

對我有用的是這個repo 中的Zip函數(81 行)

我是這樣用的

var intList = new List<int> { 1, 2, 3 };
var asyncEnumerables = intList.Select(RunAsyncIterations);
var enumerableToIterate = async_enumerable_dotnet.AsyncEnumerable.Zip(s => s, asyncEnumerables.ToArray());

await foreach (int[] enumerablesConcatenation in enumerableToIterate)
{
    Console.WriteLine(enumerablesConcatenation.Sum()); //Sum returns 6
    await Task.Delay(2000);
}

static async IAsyncEnumerable<int> RunAsyncIterations(int i)
{
    while (true)
        yield return i;
}

這是您可以使用的通用方法Zip ,實現為iterator cancellationToken裝飾與EnumeratorCancellation屬性,使得所得到的IAsyncEnumerableWithCancellation友好。

using System.Runtime.CompilerServices;

public static async IAsyncEnumerable<TSource[]> Zip<TSource>(
    IEnumerable<IAsyncEnumerable<TSource>> sources,
    [EnumeratorCancellation]CancellationToken cancellationToken = default)
{
    var enumerators = sources
        .Select(x => x.GetAsyncEnumerator(cancellationToken))
        .ToArray();
    try
    {
        while (true)
        {
            var array = new TSource[enumerators.Length];
            for (int i = 0; i < enumerators.Length; i++)
            {
                if (!await enumerators[i].MoveNextAsync()) yield break;
                array[i] = enumerators[i].Current;
            }
            yield return array;
        }
    }
    finally
    {
        foreach (var enumerator in enumerators)
        {
            await enumerator.DisposeAsync();
        }
    }
}

用法示例:

await foreach (int[] result in Zip(asyncEnumerables))
{
    Console.WriteLine($"Result: {String.Join(", ", result)}");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM