c# - 如何连接异步枚举?

标签 c# asynchronous async-await task-parallel-library ienumerable

我有一个具有此返回类型的方法:

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 .

what i'm trying an anti-pattern? I can think of one complication, exception handling - from the caller's side, the call can complete successfully and he starts using the enumerable but it can blow up midway through that...

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

关于c# - 如何连接异步枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28678066/

相关文章:

servlets - 带有嵌入式 Jetty 的异步 Servlet

rust - 如何传递包含作为引用的参数的异步回调?

C# 添加项目到 ObjectListView

c# - 增加 Azure Api 应用程序中的最大请求长度

c# - 复制文件,如果较新则覆盖

c# - 在 asp.net 发布后为空?编辑模型

c# - 延迟然后执行任务

ios - 处理并发和异步响应

c# - 比手动字典更好的选项来引用其中正在运行的方法的 'current task'?

c# - 取消 postAsync 时出现 ObjectDisposedException