Jonathan Allen已经在InfoQ网站上介绍过这个主题,我不想在这里再重复一遍,所以我建议你也阅读一下他的文章。
关键在于Task<bool> MoveNextAsync()的返回值(从bool改为Task<bool>,bool IEnumerator.MoveNext())。这样可以让整个计算和迭代都保持异步。大多数情况下,这仍然是拉取模型,即使它是异步的。IAsyncDisposable接口可用于进行异步清理。有关异步的更多信息,请点击此处。
语法最终语法应如下所示:
foreach await (var dataChunk in asyncStreams) { // 处理数据块或做一些其他的事情! }如上所示,我们现在可以按顺序计算多个值,而不只是计算单个值,同时还能够等待其他异步操作结束。
重写微软的示例我重写了微软的演示代码,你可以从我的GitHub下载相关代码。
这个例子背后的想法是创建一个大的MemoryStream(20000字节的数组),并按顺序异步迭代集合中的元素或MemoryStream。每次迭代从数组中拉取8K字节。
在(1)处,我们创建了一个大字节数组并填充了一些虚拟值。在(2)处,我们定义了一个叫作checksum的变量。我们将使用checksum来确保计算的总和是正确的。数组和checksum位于内存中,并通过一个元组返回,如(3)所示。
在(4)处,AsEnumarble(或者叫AsAsyncEnumarble)是一种扩展方法,用于模拟由8KB块组成的异步流( (6)处所示的BufferSize = 8000)。
通常,你不必继承IAsyncEnumerable,但在上面的示例中,微软这样做是为了简化演示,如(5)处所示。
(7)处是“foreach”,它从异步内存流中拉取8KB的块数据。当消费者(foreach代码块)准备好接收更多数据时,拉取过程是顺序进行的,然后它从生产者(内存流数组)中拉取更多的数据。最后,当迭代完成后,应用程序将’c’的校验和与checksum进行比较,如果它们匹配,就打印出“Checksums match!”,如(8)所示!
微软演示的输出窗口:
概要我们已经讨论过Async Streams,它是一种出色的异步拉取技术,可用于进行生成多个值的异步计算。
Async Streams背后的编程概念是异步拉取模型。我们请求获取序列的下一个元素,并最终得到答复。这与IObservable<T>的推送模型不同,后者生成与消费者状态无关的值。Async Streams提供了一种表示异步数据源的绝佳方法,例如,当消费者尚未准备好处理更多数据时。示例包含了Web应用程序或从数据库中读取记录。
我已经演示了如何生成异步枚举数据,并使用外部异步序列库来消费枚举数据。我也演示了如何将这个功能用于从Web站点下载内容。最后,我们看到了新的Async Streams语法和一个完整的示例,该示例是基于微软的Build Demo Code(2018年5月7日至9日,西雅图,华盛顿州)。
关于作者Bassam Alugili 是STRATEC AG的高级软件专家和数据库专家。STRATEC是全球领先的全自动分析仪系统、实验室数据管理软件和智能耗材的合作伙伴。