C# 8.0 抢先看-- Async Stream
Async Stream 简单说来是一种非同步的迭代器模式,说更白一点就是可以await 的foreach。在过去的C# 中如果要回传一个可迭代的IEnumerable<T> ,我们可能会这样写:
public class EnumerableProcess
{
async static public Task<IEnumerable<string>> ReadLineAsync(string path)
{
List<string> list = new List<string>();
using (StreamReader reader = File.OpenText(path))
{
while (await reader.ReadLineAsync() is string result)
{
list.Add(result);
await Task.Delay(100);
}
}
return list;
}
}
这是一个非同步一行一行读取文字档的例子,这个例子里的回传型别是一个Task<IEnumerable<string>> ,外部程式码将会这样呼叫这个方法:
var r = await EnumerableProcess.ReadLineAsync(path);
foreach (var item in r)
{
Console.WriteLine(item);
}
这造成一个长时等待的问题,因为呼叫端必须等待ReadLineAsync 这个Task 整个完成后才能回传;所以C# 8.0 引入了Async Stream 使得非同步的迭代得以实现, 这件事情不仅仅牵涉到编译器,也需要一些新的型别,主要是以下三个:
(1) IAsyncDisposable -- IAsyncEnumerator<out T> 将会拓展这个介面
public interface IAsyncDisposable
{
ValueTask DisposeAsync();
}
(2)IAsyncEnumerator <out T>
public interface IAsyncEnumerator<out T> : IAsyncDisposable
{
T Current { get; } ValueTask<bool> MoveNextAsync();
}
(3)IAsyncEnumerable <out T>
public interface IAsyncEnumerable<out T>
{
IAsyncEnumerator<T> GetAsyncEnumerator();
}
实作Async Stream
由于此时在框架中对于整个Async Stream 的实作尚未完整,所以没办法直接使用yield return,先示范最基本的写法,建立一个类别,并且实作以上介面:
sealed class AsyncFileProcess : IAsyncEnumerable<string>, IAsyncEnumerator<string>
{
private readonly StreamReader _reader; private bool _disposed;
public AsyncFileProcess(string path)
{
_reader = File.OpenText(path);
_disposed = false;
} public string Current { get; private set; }
public IAsyncEnumerator<string> GetAsyncEnumerator()
{
return this;
}
async public ValueTask<bool> MoveNextAsync()
{
await Task.Delay(100);
var result = await _reader.ReadLineAsync();
Current = result;
return result != null;
} async public ValueTask DisposeAsync()
{
await Task.Run(() => Dispose());
} private void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} private void Dispose(bool disposing)
{
if (!this._disposed)
{
if (_reader != null)
{
_reader.Dispose();
}
_disposed = true;
}
}
}
呼叫端就可以这样呼叫它:
var process = new AsyncFileProcess("SourceFile.txt");
try
{
await foreach (var s in process)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
finally
{
await process.DisposeAsync();
}
你可以感受到第一个例子是停顿了很久之后,蹦一下全跳出来;而第二的例子则会一行行跑出来(为了强化这个效果在两方都加了Task.Delay )。在第二个例子的呼叫端可以看到await foreach 的使用。
C# 8.0 抢先看-- Async Stream的更多相关文章
- 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单
一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...
- 转:[你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单
本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单 async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...
- [你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单
本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单 async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...
- [译] C# 5.0 中的 Async 和 Await (整理中...)
C# 5.0 中的 Async 和 Await [博主]反骨仔 [本文]http://www.cnblogs.com/liqingwen/p/6069062.html 伴随着 .NET 4.5 和 V ...
- Android P新功能特性抢先看
2018年3月8日,Google推出了Android P Preview版本,并提供官方镜像下载. 为了让广大开发者能够及时了解Android P的新功能特性,提前为您的app进行良好适配,WeTes ...
- 四、C# 5.0 新特性——Async和Await使异步编程更简单
一.引言 .NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就 ...
- [转帖]CentOS 8.0.1905 和CentOS Stream(滚动发行)正式发布
CentOS 8.0.1905 和CentOS Stream(滚动发行)正式发布 https://zhuanlan.zhihu.com/p/84001292 还发现openssl 的 版本太高 不兼容 ...
- C#5.0 异步编程 Async和Await--异步方法的规范和注意事项
要些异步方法要注意一下几点: 异步方法的返回值有三种: 1.没有任何返回值的void 2.返回一个Task任务的Task,可以获得该异步方法的执行状态 3.返回Task<T> 可以获得异步 ...
- 【转】OpenStack奥斯汀峰会Keynotes国内抢先看
http://www.openstack.cn/?p=5341 OpenStack奥斯汀峰会Keynotes国内抢先看入口:http://www.tudou.com/home/_903780397/i ...
随机推荐
- thinkphp 操作xml格式
前言:虽然xml的格式看起来跟html差不多,但是最近做项目由于用的是thinkphp5.0的版本,做的过程中还是遇到了一些问题.在这里做一下记录. 首先我们需要定义一个dom对象,我们都知道 php ...
- 【笔记】Nginx热更新相关知识
(以下学习笔记内容均摘自参考链接,仅供个人查阅) 1.inotify文件系统监控特性 Inotify 是一个 Linux 内核特性,它监控文件系统,并且及时向专门的应用程序发出相关的事件警告,比如 ...
- Error:Execution failed for task ':app:preDebugAndroidTestBuild'. > Conflict with dependency 'com.android.support:support-annotations' in project ':app'. Resolved versions for app (26.1.0) and test app
出现的问题: Error:Execution failed for task ':app:preDebugAndroidTestBuild'.> Conflict with dependency ...
- Eclipse下运行maven项目失败且Tomcat服务器也启动不了
今天遇到一个神奇的问题,在eclipse中创建一个maven项目后,Run on server 时说服务器启动失败.我以为是Eclipse配置tomcat的问题.找了一大堆没找到想要的答案!!! 我还 ...
- kubernetes1.13.5安装部署
Kubernetes 一. Kubernetes介绍 各节点所需组件 Master:docker,kubeadm,kubelet, 组件 版本 备注 Kubelet 1.13.5 组件 Kube ...
- 《c++ concurrency in action》读书笔记1
1. 什么是并发通俗来说,并发指两个或者多个独立的事件(活动)同时发生.比如,一边走路一边说话,两个手同时做不同的事情.计算机系统的并发是指一个系统并行处理多个独立的事件(活动), 而不是按顺序或者一 ...
- spring boot2.0(一 ) 基础环境搭建
1.基础配置 开发环境:window jdk版本:1.8(spring boot2.0最低要求1.8) 开发工具:eclipse 构建方式:maven3 2.POM配置文件 <project x ...
- .NetCore WebApi
1.简单请求 [HttpGet] public ActionResult Get(int id) Postman: api / controller / action?id=1 2.form-data ...
- 下载网站js css img 资源
- .net core 连接mysql
Package引入: mysql.data MySql.Data.EntityFrameworkCore Pomelo.EntityFrameworkCore.MySql 2. 在package ma ...