翻譯|使用教程|編輯:吳園園|2019-10-21 10:04:16.260|閱讀 395 次
概述:本文將為您帶來異步流– C#8中的新語言功能介紹。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
ReSharper是一個著名的代碼生成工具,其能幫助Microsoft Visual Studio成為一個更佳的IDE。實質(zhì)上,ReSharper特征可用于C#,VB.net,XML,Asp.net,XAML,和構(gòu)建腳本。
ReSharper Ultimate 2019.2提供了對C#8.0的更好支持以及一些Navigation,F(xiàn)ind Usages和調(diào)試器數(shù)據(jù)提示的更新。它還改善了啟動時間,并為VS 2019中的“Per-Monitor DPI Awareness”模式提供了初始支持.C ++項目的索引更快,支持更多C ++ 20功能。點(diǎn)擊查看更新詳情!
自從C#8系列的最后一部分以來已經(jīng)有一段時間了,但是它來了!我們將繼續(xù)通過新的語言功能進(jìn)行探索,并深入到異步流中。
在本系列中,我們正在研究:
指數(shù),范圍和空值分配
切換表達(dá)式和基于模式的用法
遞歸模式匹配
異步流
異步編程是一種編程形式,它可以通過允許將耗時的工作(例如從網(wǎng)絡(luò)下載數(shù)據(jù))與主線程分離來防止阻塞我們的應(yīng)用程序。對于我們的實現(xiàn),原則上,它需要將回調(diào)傳遞給異步方法,該異步方法又會在完成工作后調(diào)用該回調(diào)。
在C#5中,引入了async和await關(guān)鍵字。這些從根本上改善了我們編寫和使用異步方法的方式。基本上,與同步實現(xiàn)相比,我們的代碼結(jié)構(gòu)可以保持幾乎相同,但是編譯器接管了很多工作,將我們的代碼重組為上述回調(diào),以使其具有狀態(tài)且無阻塞。但是,這僅適用于使用Task和Task<T>作為返回類型的void和單結(jié)果方法。
產(chǎn)生數(shù)據(jù)流的方法(又名IEnumerable<T>)被省去了,需要編寫自定義代碼。但是,此類要求非常普遍,例如考慮使用云應(yīng)用程序,從IoT傳感器收集數(shù)據(jù)或從數(shù)據(jù)庫接收數(shù)據(jù)。,C#8和IAsyncEnumerable!
隨著.NET 2.1標(biāo)準(zhǔn)的發(fā)布,引入了一組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接口的異步版本。您可能已經(jīng)猜到了,它叫做IAsyncDisposable:
public interface IAsyncDisposable { ValueTask DisposeAsync(); }
從.NET Core SDK 3.0開始,實際上已經(jīng)實現(xiàn)了這些類型,并且使用C#8 foreach,using可以將and 關(guān)鍵字作為前綴await與IAsyncEnumerableand IAsyncDisposable實例一起使用。
IAsyncEnumerable<T>實質(zhì)上,迭代意味著獲取下一個對象成為異步操作,而foreach主體成為我們的回調(diào)。只有當(dāng)我們繼續(xù)循環(huán)時,才會提取一個新項目(與調(diào)用相對break)。這基本上將這種方法標(biāo)記為基于拉的方法。該await foreach語句還基于模式工作,這意味著它將與提供適當(dāng)GetAsyncEnumerator方法但不實現(xiàn)IAsyncEnumerable<T>接口的任何類型一起工作。
讓我們看看如何將這些添加項組合使用。好奇的開發(fā)人員絕對應(yīng)該抓住機(jī)會,看看它的反編譯代碼:
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標(biāo)記有一個EnumeratorCancellation屬性。與JetBrains.Annotations包中的EnumeratorCancellation屬性相似,該屬性(包含在中System.Runtime.CompilerServices)將代碼片段標(biāo)記為其他魔術(shù),這些魔術(shù)目前還無法用語言本身來表達(dá)。
如前所述,using語句現(xiàn)在也可以使用await關(guān)鍵字作為前綴。讓我們一起來看看!
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標(biāo)準(zhǔn)2.1,兩個所涉及的類型FileStream,并StreamWriter都實現(xiàn)IAsyncDisposable。這樣就可以異步完成所有處理工作,例如刷新磁盤更改。
ReSharper和Rider能為我做什么?
除了解析新的語言結(jié)構(gòu)外,ReSharper和Rider還帶來了其他一些有助于異步流工作的優(yōu)點(diǎn)。
從我們可以枚舉的最明顯的操作開始,foreach 后綴模板已更新為完成,await foreach直到有問題的枚舉類型為IAsyncEnumerable<T>或匹配其模式:
在最后一個示例中,我們犯了一個錯誤。我們沒有通過取消令牌!幸運(yùn)的是,這里進(jìn)行了新的代碼檢查,并提供了一個快速修復(fù)程序來使事情正確:
等等,還有另一個棘手的示例,其中ReSharper和Rider將注意到可以使用WithCancellation擴(kuò)展方法傳遞取消令牌。還記得EnumeratorCancellation我們提到的屬性嗎?這將允許編譯器用與原始令牌組合的有效取消令牌替換取消令牌的每種用法IAsyncEnumerator:
每當(dāng)我們想要返回an IAsyncEnumerable<T>但該方法尚未標(biāo)記時async,ReSharper和Rider都會建議從方法名稱區(qū)域或從await出現(xiàn)的關(guān)鍵字中返回:
同樣,當(dāng)我們使用已標(biāo)記為的方法時async,ReSharper和Rider將允許從錯誤定義的IEnumerable<T>返回類型更改為IAsyncEnumerable<T>:
在消費(fèi)方面,另一種快速修復(fù)方法是將同步foreach語句更改為異步await foreach語句。在轉(zhuǎn)換現(xiàn)有代碼以利用新的語言功能時,這可能很有用:
最后但并非最不重要的一點(diǎn),讓我們回到IAsyncDisposable并等待使用。如果方法是async,并且所討論的對象實現(xiàn)了異步對象DisposeAsync,則Rider和ReSharper將顯示檢查結(jié)果,await using可以代替使用。同樣,我們可以將await using語句轉(zhuǎn)換為基于模式的using中描述的聲明。相應(yīng)的快速修復(fù)可以在范圍內(nèi)應(yīng)用:
=====================================================
想要了解或購買ReSharper正版授權(quán)的朋友,歡迎
關(guān)注下方“慧聚IT”微信公眾號,及時獲取產(chǎn)品最新消息和最新資訊
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: