Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何处理异步枚举?_C#_Asynchronous_Async Await_Task Parallel Library_Ienumerable - Fatal编程技术网

C# 如何处理异步枚举?

C# 如何处理异步枚举?,c#,asynchronous,async-await,task-parallel-library,ienumerable,C#,Asynchronous,Async Await,Task Parallel Library,Ienumerable,我有一个返回类型为的方法: public async Task<IEnumerable<T>> GetAll() 现在,等待所有结果并对结果进行concat以生成单个可枚举项非常容易,但我希望在第一次调用返回时,该可枚举项就可以使用,如果可用结果用完时仍有任何调用挂起,则可能会等待调用方/枚举器 我是否必须为此手动滚动一个concat,解决在任务中包装枚举器时缺少枚举器支持的问题?或者TPL或其他地方已经有一个图书馆电话可以帮助我。我确实看过IX,但它仍然是实验版本,不

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

public async Task<IEnumerable<T>> GetAll()
现在,等待所有结果并对结果进行concat以生成单个可枚举项非常容易,但我希望在第一次调用返回时,该可枚举项就可以使用,如果可用结果用完时仍有任何调用挂起,则可能会等待调用方/枚举器

我是否必须为此手动滚动一个concat,解决在任务中包装枚举器时缺少枚举器支持的问题?或者TPL或其他地方已经有一个图书馆电话可以帮助我。我确实看过IX,但它仍然是实验版本,不想把它折叠起来


另一方面,我所尝试的是反模式吗?我可以想到一个复杂的问题,异常处理——从调用方的角度来看,调用可以成功完成,他开始使用可枚举项,但它可能会在中途爆炸……

有一个名为的现有项目准确地回答了这个问题

你可以很容易地使用它

例如:

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 GetAsyncAnswers()
{
返回AsyncEnum.Enumerate(异步使用者=>
{
foreach(GetQuestions()中的变量问题)
{
string theAnswer=wait answeringService.GetAnswer(问题);
等待消费者。YieldAsync(答案);
}
});
}
这将公开一个
IAsyncEnumerable
,它将生成一次
GetAnswer
返回。在您的案例中,您可以在内部公开一个
IAsyncEnumerable
,并在内部调用
GetAll

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


我不会这么说。这确实存在潜在的问题,例如在一次等待期间内部发生异常,但这也可能发生在任何
IEnumerable
内部。异步序列在今天新兴的异步API的现实中是需要的。

(作为旁注)您的模式似乎是不对称的:代码等待第一个序列准备好,但不等待其余的。也许您真的需要
IObservable
?如果是那样的话,你可以直接使用。@Vlad:说得好。当我查看Ix/Rx时,我确实想到了这一点,我同意,reactive确实更适合这种类型的用例。但是整个场景和应用程序都是基于拉的,我不想只是为了从可观察的结果返回到可枚举的结果而对Rx进行讨论。谢谢。标记为答案的。我没有导入库,但最终还是将我自己的库以类似的两行滚动到您的示例中,通过一个连接器获取func以获取下一个可枚举项。如果我得到一个更广泛的用例,也许我会再看看这个库。
IAsyncEnumerable<string> GetAsyncAnswers()
{
    return AsyncEnum.Enumerate<string>(async consumer =>
    {
        foreach (var question in GetQuestions())
        {
            string theAnswer = await answeringService.GetAnswer(question);
            await consumer.YieldAsync(theAnswer);
        }
    });
}