ReSharper是一个著名的代码生成工具,其能帮助Microsoft Visual Studio成为一个更佳的IDE。实质上,ReSharper特征可用于C#,VB.net,XML,Asp.net,XAML,和构建脚本。
ReSharper Ultimate 2019.2提供了对C#8.0的更好支持以及一些Navigation,Find Usages和调试器数据提示的更新。它还改善了启动时间,并为VS 2019中的“Per-Monitor DPI Awareness”模式提供了初始支持.C ++项目的索引更快,支持更多C ++ 20功能。点击查看更新详情!
ReSharper最新试用版
自从C#8系列的最后一部分以来已经有一段时间了,但是它来了!我们将继续通过新的语言功能进行探索,并深入到异步流中。
在本系列中,我们正在研究:
-
指数,范围和空值分配
-
切换表达式和基于模式的用法
-
递归模式匹配
-
异步流
- 可空引用类型
异步编程是一种编程形式,它可以通过允许将耗时的工作(例如从 络下载数据)与主线程分离来防止阻塞我们的应用程序。对于我们的实现,原则上,它需要将回调传递给异步方法,该异步方法又会在完成工作后调用该回调。
在C#5中,引入了async和await关键字。这些从根本上改善了我们编写和使用异步方法的方式。基本上,与同步实现相比,我们的代码结构可以保持几乎相同,但是编译器接管了很多工作,将我们的代码重组为上述回调,以使其具有状态且无阻塞。但是,这仅适用于使用Task和Task<T>作为返回类型的void和单结果方法。
产生数据流的方法(又名IEnumerable<T>)被省去了,需要编写自定义代码。但是,此类要求非常普遍,例如考虑使用云应用程序,从IoT传感器收集数据或从数据库接收数据。,C#8和IAsyncEnumerable!
随着.NET 2.1标准的发布,引入了一组3个接口: IAsyncDisposable,IAsyncEnumerable<T>和IAsyncEnumerator<T>。这些接口允许我们以某种方式表示的异步版本IEnumerable<T>,从而使用异步流:
public interface IAsyncDisposable{ ValueTask DisposeAsync();}public interface IAsyncEnumerable<out T>{ IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken token = default);}public interface IAsyncEnumerator<out T> : IAsyncDisposable{ ValueTask<bool> MoveNextAsync(); T Current { get; }}
为了IAsyncEnumerable<T>在各种情况下都能正常工作(如await在finally块中一样),我们还需要IDisposable接口的异步版本。您可能已经猜到了,它叫做IAsyncDisposable:
public interface IAsyncDisposable{ ValueTask DisposeAsync();}
从.NET Core SDK 3.0开始,实际上已经实现了这些类型,并且使用C#8 foreach,using可以将and 关键字作为前缀await与IAsyncEnumerableand IAsyncDisposable实例一起使用。
IAsyncEnumerable<T>实质上,迭代意味着获取下一个对象成为异步操作,而foreach主体成为我们的回调。只有当我们继续循环时,才会提取一个新项目(与调用相对break)。这基本上将这种方法标记为基于拉的方法。该await foreach语句还基于模式工作,这意味着它将与提供适当GetAsyncEnumerator方法但不实现IAsyncEnumerable<T>接口的任何类型一起工作。
让我们看看如何将这些添加项组合使用。好奇的开发人员绝对应该抓住机会,看看它的反编译代码:
static async Task Main(){ await foreach (var data in ReadAndNormalize()) { Console.WriteLine(data); }}static async IAsyncEnumerable<Data> ReadAndNormalize( [EnumeratorCancellation] CancellationToken token = default){ while (!token.IsCancellationRequested) { var data = await ReadInputFromDevice(); var normalizedData = ConvertAndNormalize(data); yield return normalizedData; }}static async Task<byte[]> ReadInputFromDevice() { return default; }static Data ConvertAndNormalize(byte[] data) { return default; }struct Data { }
请注意,CancellationToken标记有一个EnumeratorCancellation属性。与JetBrains.Annotations包中的EnumeratorCancellation属性相似,该属性(包含在中System.Runtime.CompilerServices)将代码片段标记为其他魔术,这些魔术目前还无法用语言本身来表达。
如前所述,using语句现在也可以使用await关键字作为前缀。让我们一起来看看!
async Task WriteToFileAsync(string file){ await using (var fs = new FileStream(file, FileMode.CreateNew)) await using (var sw = new StreamWriter(fs)) { await sw.WriteAsync("Hello C#8!"); }}
由于.NET标准2.1,两个所涉及的类型FileStream,并StreamWriter都实现IAsyncDisposable。这样就可以异步完成所有处理工作,例如刷新磁盘更改。
ReSharper和Rider能为我做什么/strong>
除了解析新的语言结构外,ReSharper和Rider还带来了其他一些有助于异步流工作的优点。
Rider最新试用版
从我们可以枚举的最明显的操作开始,foreach 后缀模板已更新为完成,await foreach直到有问题的枚举类型为IAsyncEnumerable<T>或匹配其模式:
标签:
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!