如何连接异步枚举



我有一个返回类型为的方法

public async Task<IEnumerable<T>> GetAll()

它进行了一些进一步的异步调用(未知数量),每个调用都返回一个可枚举T的任务,然后希望合并返回的结果。

var data1 = src1.GetAll();
var data2 = src2.GetAll();
var data3 = src3.GetAll(); //and so on

现在,等待所有结果并合并结果以生成单个可枚举对象已经很容易了,但我希望第一个调用返回时可枚举对象就可用,如果可用结果用完时任何调用仍处于挂起状态,则可能会等待调用者/枚举器。

我是否必须手动滚动一个concat,以解决在任务中封装时缺少枚举器支持的问题<>?或者在TPL或其他地方已经有一个库调用可以帮助我。我确实看过IX,但它仍在实验版本中,不想折叠它。

顺便说一句,我正在尝试的是反模式吗?我可以想到一个复杂的问题,异常处理——从调用者的角度来看,调用可以成功完成,他开始使用枚举,但它可能会在中途爆炸。。。

有一个名为Async Enumerable的现有项目正好解决了这个问题。

你可以很容易地使用它。

例如:

IAsyncEnumerable<string> GetAsyncAnswers()
{
    return AsyncEnum.Enumerate<string>(async consumer =>
    {
        foreach (var question in GetQuestions())
        {
            string theAnswer = await answeringService.GetAnswer(question);
            await consumer.YieldAsync(theAnswer);
        }
    });
}

这公开了一个IAsyncEnumerable<string>,一旦GetAnswer返回就会产生。您可以在内部公开案例中的IAsyncEnumerable<T>,并在内部调用GetAll

我在尝试什么反模式?我能想到一个复杂的问题,异常处理-从调用方一侧,调用可以完成成功,他开始使用枚举器,但它可能会爆炸中途。。。

我不会这么说。这确实存在潜在的问题,例如在等待过程中内部发生异常,但这也可能在任何IEnumerable<T>内部发生。异步序列是当今新兴的异步API的现实所需要的。

最新更新