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 的使用。
轉載于:https://www.cnblogs.com/wwwblender-3dcn/p/10162224.html
總結
以上是生活随笔為你收集整理的C# 8.0 抢先看-- Async Stream的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷3613睡觉困难综合征(LCT维护链
- 下一篇: vmware三种网络模式配置(转载)