最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#中的高效IO庫System.IO.Pipelines

 更新時(shí)間:2022年07月02日 09:33:03   作者:天方  
這篇文章介紹了C#中的高效IO庫System.IO.Pipelines,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

我們在編寫網(wǎng)絡(luò)程序的時(shí)候,經(jīng)常會進(jìn)行如下操作:

  • 申請一個(gè)緩沖區(qū)

  • 從數(shù)據(jù)源中讀入數(shù)據(jù)至緩沖區(qū)

  • 解析緩沖區(qū)的數(shù)據(jù)

  • 重復(fù)第2步

表面上看來這是一個(gè)很常規(guī)而簡單的操作,但實(shí)際使用過程中往往存在如下痛點(diǎn):

數(shù)據(jù)讀不全:

可能不能在一次read操作中讀入所有需要的數(shù)據(jù),因此需要在緩沖區(qū)中維護(hù)一個(gè)游標(biāo),記錄下次讀取操作的起始位置,這個(gè)游標(biāo)帶了了不小的復(fù)雜度:

  • 從緩沖區(qū)讀數(shù)據(jù)時(shí),要根據(jù)游標(biāo)計(jì)算緩沖區(qū)起始寫位置,以及剩余空間大小。增加了讀數(shù)據(jù)的復(fù)雜度。

  • 解析數(shù)據(jù)也是復(fù)用這個(gè)緩沖區(qū)的,解析的時(shí)候也要判斷游標(biāo)起始位置,剩余空間大小。同時(shí)增加了解析數(shù)據(jù)的復(fù)雜度。

  • 解析玩了后還要移動(dòng)游標(biāo),重新標(biāo)記緩沖區(qū)起始位置,再次增加了復(fù)雜度。

緩沖區(qū)容量有限:

由于緩沖區(qū)有限,可能申請的緩沖區(qū)不夠用,需要引入動(dòng)態(tài)緩沖區(qū)。這也大幅加大了代碼的復(fù)雜度。

  • 如果每次都申請更大的內(nèi)存,一方面帶來的內(nèi)存申請釋放開銷,另一方面需要將原來的數(shù)據(jù)移動(dòng),并更新游標(biāo),帶來更復(fù)雜的邏輯。

  • 如果靠多段的內(nèi)存組成一個(gè)邏輯整理,數(shù)據(jù)的讀寫方式都比較復(fù)雜。

  • 使用完后的內(nèi)存要釋放,如果需要更高的效率還要維持一個(gè)內(nèi)存池。

讀和用沒有分離

我們的業(yè)務(wù)本身只關(guān)心使用操作,但讀和用操作沒有分離,復(fù)雜的都操作導(dǎo)致用操作也變得復(fù)雜,并且嚴(yán)重干擾業(yè)務(wù)邏輯。

今天介紹微軟新推出的一個(gè)庫:System.IO.Pipelines(需要在Nuget上安裝),用于解決這些痛點(diǎn)。它主要包含一個(gè)Pipe對象,它有一個(gè)Writer屬性和Reader屬性。

var pipe   = new Pipe();
var writer = pipe.Writer;
var reader = pipe.Reader;

Writer對象

Writer對象用于從數(shù)據(jù)源讀取數(shù)據(jù),將數(shù)據(jù)寫入管道中;它對應(yīng)業(yè)務(wù)中的"讀"操作。

var?content?=?Encoding.Default.GetBytes("hello?world");
var?data????=?new?Memory<byte>(content);
var?result??=?await?writer.WriteAsync(data);

另外,它也有一種使用Pipe申請Memory的方式

var?buffer?=?writer.GetMemory(512);
content.CopyTo(buffer);
writer.Advance(content.Length);
var?result?=?await?writer.FlushAsync();

Reader對象

Reader對象用于從管道中獲取數(shù)據(jù)源,它對應(yīng)業(yè)務(wù)中的"用"操作。

首先獲取管道的緩沖區(qū):

var?result?=?await?reader.ReadAsync();
var?buffer?=?result.Buffer;

這個(gè)Buffer是一個(gè)ReadOnlySequence<byte>對象,它是一個(gè)相當(dāng)好的動(dòng)態(tài)內(nèi)存對象,并且相當(dāng)高效。它本身由多段Memory<byte>組成,查看Memory段的方法有:

  • IsSingleSegment: 判斷是否只有一段Memory<byte>

  • First: 獲取第一段Memory<byte>

  • GetEnumerator: 獲取分段的Memory<byte>

它從邏輯上也可以看成一段連續(xù)的Memory<byte>,也有類似的方法:

  • Length: 整個(gè)數(shù)據(jù)緩沖區(qū)長度

  • Slice: 分割緩沖區(qū)

  • CopyTo: 將內(nèi)容復(fù)制到Span中

  • ToArray: 將內(nèi)容復(fù)制到byte[]中

另外,它還有一個(gè)類似游標(biāo)的位置對象SequencePosition,可以從其Position相關(guān)函數(shù)中使用,這里就不多介紹了。

這個(gè)緩沖區(qū)解決了"數(shù)據(jù)讀不夠"的問題,一次讀取的不夠下次可以接著讀,不用緩沖區(qū)的動(dòng)態(tài)分配,高效的內(nèi)存管理方式帶來了良好的性能,好用的接口是我們能更關(guān)注業(yè)務(wù)。

獲取到緩沖區(qū)后,就是使用緩沖區(qū)的數(shù)據(jù)

var?data?=?buffer.ToArray();

使用完后,告訴PIPE當(dāng)前使用了多少數(shù)據(jù),下次接著從結(jié)束位置后讀起

reader.AdvanceTo(buffer.GetPosition(4));

這是一個(gè)相當(dāng)實(shí)用的設(shè)計(jì),它解決了"讀了就得用"的問題,不僅可以將不用的數(shù)據(jù)下次再使用,還可以實(shí)現(xiàn)Peek的操作,只讀但不改變游標(biāo)。

交互

除了"讀"和"用"操作外,它們之間還需要一些交互,例如:

  • 讀過程中數(shù)據(jù)源不可用,需要停止使用

  • 使用過程中業(yè)務(wù)結(jié)束,需要中止數(shù)據(jù)源。

Reader和Writer都有一個(gè)Complete函數(shù),用于通知結(jié)束:

reader.Complete();
writer.Complete();

在Writer寫入和Reader讀取時(shí),會獲得一個(gè)結(jié)果

FlushResult?result?=?await?writer.FlushAsync();
ReadResult?result?=?await?reader.ReadAsync();

它們都有一個(gè)IsComplete屬性,可以根據(jù)它是否為true判斷是否已經(jīng)結(jié)束了讀和寫的操作。

取消

在寫入和讀取的時(shí)候,也可以傳入一個(gè)CancellationToken,用于取消相應(yīng)的操作。

writer.FlushAsync(CancellationToken.None);
reader.ReadAsync(CancellationToken.None);

如果取消成功,對應(yīng)的Result的IsCanceled則為true(沒有驗(yàn)證過)

到此這篇關(guān)于C#高效IO庫System.IO.Pipelines的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • VS2017使用Git進(jìn)行源代碼管理的實(shí)現(xiàn)

    VS2017使用Git進(jìn)行源代碼管理的實(shí)現(xiàn)

    這篇文章主要介紹了VS2017使用Git進(jìn)行源代碼管理的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • C#圖表算法之最短路徑

    C#圖表算法之最短路徑

    本文詳細(xì)講解了C#圖表算法之最短路徑,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C# paddlerocrsharp識別身份證號的實(shí)現(xiàn)示例

    C# paddlerocrsharp識別身份證號的實(shí)現(xiàn)示例

    paddlerocrsharp可以進(jìn)行圖片識別,本文主要介紹了C# paddlerocrsharp識別身份證號的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • 詳談C# 圖片與byte[]之間以及byte[]與string之間的轉(zhuǎn)換

    詳談C# 圖片與byte[]之間以及byte[]與string之間的轉(zhuǎn)換

    下面小編就為大家?guī)硪黄斦凜# 圖片與byte[]之間以及byte[]與string之間的轉(zhuǎn)換。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02
  • Unity實(shí)現(xiàn)車型識別的示例代碼

    Unity實(shí)現(xiàn)車型識別的示例代碼

    這篇文章主要介紹了在Unity中接入百度AI,實(shí)現(xiàn)檢測一張車輛圖片的具體車型。即對于輸入的一張圖片(可正常解碼,且長寬比適宜),輸出圖片的車輛品牌及型號。需要的可以參考一下
    2022-01-01
  • C#獲取Description特性的擴(kuò)展類詳解

    C#獲取Description特性的擴(kuò)展類詳解

    這篇文章主要和大家詳細(xì)介紹一下C#獲取Description特性的擴(kuò)展類,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)有一定的幫助,需要的可以參考一下
    2022-06-06
  • C# 設(shè)計(jì)模式系列教程-簡單工廠模式

    C# 設(shè)計(jì)模式系列教程-簡單工廠模式

    簡單工廠模式職責(zé)單一,實(shí)現(xiàn)簡單,且實(shí)現(xiàn)了客戶端代碼與具體實(shí)現(xiàn)的解耦。
    2016-06-06
  • c# winform取消右上角關(guān)閉按鈕的實(shí)現(xiàn)方法

    c# winform取消右上角關(guān)閉按鈕的實(shí)現(xiàn)方法

    本文是對c#中winform取消右上角關(guān)閉按鈕的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下。希望對大家有所幫助
    2013-10-10
  • C#9新特性之增強(qiáng)的模式匹配

    C#9新特性之增強(qiáng)的模式匹配

    這篇文章主要介紹了C#9新特性之增強(qiáng)的模式匹配,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Quartz.Net任務(wù)和觸發(fā)器實(shí)現(xiàn)方法詳解

    Quartz.Net任務(wù)和觸發(fā)器實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了Quartz.Net任務(wù)和觸發(fā)器實(shí)現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12

最新評論

华安县| 永新县| 西乌| 同江市| 商河县| 扶余县| 临高县| 金塔县| 南阳市| 嘉兴市| 神木县| 神池县| 四会市| 博湖县| 辰溪县| 同德县| 武乡县| 山东省| 阜阳市| 乌拉特后旗| 冷水江市| 安阳市| 昭平县| 定安县| 奉新县| 山东省| 元江| 嘉鱼县| 波密县| 柘荣县| 思茅市| 绥江县| 仪陇县| 隆尧县| 洪雅县| 巴彦淖尔市| 化德县| 会宁县| 津市市| 马边| 方山县|