异步流——消耗异步流
问题
假设需要处理异步流的结果,这个过程也叫作异步枚举
#解决方案
消耗异步操作可以通过await来实现,消耗枚举通常通过foreach实现。消耗异步枚举则要将这两者结合起来,也就是使用await foreach来实现。假设现在有一个异步枚举,它会对API响应分页,我们可以消耗它并把每个元素写入控制台:
IAsyncEnumerable<string> GetValuesAsync(HttpClient client);
public async Task ProcessValueAsync(HttpClient client)
{
await foreach(string value in GetValuesAsync(client))
{
Console.WriteLine(value);
}
}
从概念上看,GetValuesAsync被调用后返回IAsyncEnumerable<T>。然后foreach从该异步枚举创建了异步枚举器。在异步枚举器重,获取下一个元素这已操作可能是一步的。await foreach会等待下一个元素的到来。或者等待异步枚举器完成,如有元素传来,await foreach会执行其循环代码体,如果异步枚举器已经完成,就会退出循环。
讨论
await foreach 是消耗异步流最最然的方式。C#支持ConfigureAwait(false),用来避免await foreach的上下文
传入取消令牌也是可行的