桂林景区网站策划,wordpress 路由自定义页面,wordpress_zh,手机作网站服务器C# 8.0中#xff0c;提供了一种新的IAsyncEnumerableT接口#xff0c;在对集合进行迭代时#xff0c;支持异步操作。比如在读取文本中的多行字符串时#xff0c;如果读取每行字符串的时候使用同步方法#xff0c;那么会导致线程堵塞。IAsyncEnumerableT可… C# 8.0中提供了一种新的IAsyncEnumerableT接口在对集合进行迭代时支持异步操作。比如在读取文本中的多行字符串时如果读取每行字符串的时候使用同步方法那么会导致线程堵塞。IAsyncEnumerableT可以解决这种情况在迭代的时候支持使用异步方法。也就是说之前我们使用foreach来对IEnumerable进行迭代现在可以使用await foreach来对IAsyncEnumerableT进行迭代每个项都是可等待的。这种新的接口称为async-streams将会随.NET Core 3发布。我们来看一下如何在LINQ中实现异步的迭代。使用常规的IEnumerableT首先我们创建一个新的Console项目基于.NET Core 3这是一个很简单的Console程序实现了一个简单的返回类型为IEnumerablestring的ReadAllLines(string file)方法从文本文件中逐行读取文本并逐行输出。如果文本内容较少的话没什么问题。但如果我们使用过aync/await就会了解在IO操作如读取或写入文件的时候最好使用异步方法以避免线程阻塞。让我们来改进一下。使用异步的IAsyncEnumerableT可以优化的是下面这句对于IO操作最好使用异步方式。这里可使用相应的异步方法我们说“异步是传染的”如果这里使用异步那么相应的该方法的返回值也要使用异步所以需要将返回值改为static async TaskIEnumerablestring但这样会得到一个错误因为TaskIEnumerablestring并不是一个可以迭代的接口类型所以我们无法在方法内部使用yield关键字。解决问题的办法是使用新的IAsyncEnumerable接口按F12查看该接口的定义这是一个异步的迭代器并提供了CancellationToken。再按F12查看IAsyncEnumeratorT的定义可发现里面是这样的这里MoveNextAsync()方法实际是返回了一个结果类型为bool的Task每次迭代都是可等待的从而实现了迭代器的异步。使用await foreach消费IAsyncEnumerableT当我们做了以上改动之后ReadAllLines()方法返回的是一个支持异步的IAsyncEnumerable那么在使用的时候也不能简单的使用foreach了。修改Main方法如下首先在foreach之前添加await关键字还要需要将Main方法由void改为async Task。这样整个程序都是异步执行了不会再导致堵塞了。这个例子只是一个简单的demo是否使用异步并不会感觉到明显的区别。如果在迭代内部需要比较重的操作如从网络获取大量数据或读取大量磁盘文件异步的优势还是会比较明显的。使用LINQ消费IAsyncEnumerableT使用LINQ来操作集合是常用的功能。如果使用IEnumberable在Main方法中可以做如下改动或如果使用了新的IAsyncEnumerable你会发现无法使用Where等操作符了目前LINQ还没有提供对IAsyncEnumerable的原生支持不过微软提供了一个Nuget包来实现此功能。在项目中打开Nuget Package Manger搜索安装System.Linq.Async注意该包目前还是预览版所以要勾选include prerelease才能看到。安装该Nuget包后Linq查询语句中的错误就消失了。在System.Linq.Async这个包中对每个同步的LINQ方法都做了相应的扩展。所以基本上代码无需什么改动即可正常编译。对于LINQ中的条件语句也可以使用WhereAwait()方法来支持await如需要在条件语句中进行IO或网络请求等异步操作可以这样用DoSomeHeavyOperationsAsync方法的签名如下小结通过以上的示例我们简要了解了如何使用IAsyncEnumerable接口以及如何在LINQ中实现异步查询。在使用该接口时我们需要创建一个自定义方法返回IAsyncEnumerableT来代替IEnumberableT这个方法可称为async-iterator方法需要注意以下几点该方法应该被声明为async。返回IAsyncEnumerableT。同时使用await及yield。如await foreachyield return或yield break等。例如此外还有一些限制无法在try的finally块中使用任何形式的yield语句。无法在包含任何catch语句的try语句中使用yield return语句。期待.NET Core 3的正式发布点个赞再走呗?