日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Dotnet Core下的Channel, 你用了吗?

發布時間:2023/12/4 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dotnet Core下的Channel, 你用了吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天給大家分享一個微軟官方的好東西:Channel。

?

前言

今天給大家分享一個微軟官方的生產者/消費者方案的特性解決:Channel。

Channel在System.Threading.Channels命名空間下,Core 2.1使用時,需要從Nuget上安裝。

%?dotnet?add?package?System.Threading.Channels

而在Core 3.0 preview 7開始,就直接包含在框架中了。

?

這是一個相對較新的特性。從Core 2.1開始加入,現在版本是5.0.0(嗯,這個版本號有點騙人,Channel的第一個版本就是4.5.0)。

Channel能做什么?

邏輯上,Channel實際就是一個高效的、線程安全的隊列,支持在生產者和消費者之間傳遞數據。

利用Channel,通過發布和訂閱,可以將生產者和消費者分開。生產者Producer負責接收請求,并寫入Channel,而消費者Consumer為每個進入Channel的數據執行處理。這樣做,一方面可以使生產者和消費者并行工作來提高性能,另一方面,可以通過創建更多的生產者或消費者來提高應用的吞吐量。

下面,我們以一個實際例子,來解釋這個特性。

創建Channel

Channel提供了一個靜態Channel類,提供了兩個公開方法來創建兩種類型的Channel。

  • CreateUnbounded - 創建一個具有無限容量的Channel。

  • CreateBounded - 創建一個具有有限容量的Channel。

人通常來說,這兩種方式使用上沒有太大的區別。實際應用中,具體要看生產和消費的速度,以及期望產生的結果。有限容量的Channel,容量是有上限的,到達上限后,可以讓生產者非阻塞等待消費者使用并釋放Channel容量后再繼續。這種方式,好處是可以控制生產的速度,控制系統資源的使用,缺點也是。因為控制速度意味著生產速度會被限制,甚至停止。而無限容量,生產者可以全速進行生產。但也有缺點,如果消費者的消費速度低于生產者,Channel的資源使用會無限增加,會有服務器資源耗盡的可能。

?

今天的例子,我們使用無限Channel。

var?channel?=?Channel.CreateUnbounded<string>();

非常簡單的一行代碼,就創建了一個無限容量的Channel。

我們定義這個Channel用來保存字符串對象。

創建方法是一個通用的工廠方法,所以我們可以為需要使用的任何類型的對象和數據創建Channel。

?

Channel有兩個屬性:閱讀器返回ChannelReader,寫入器返回ChannelWriter。

寫入Channel

使用寫入器ChannelWriter,可以對Channel進行寫入操作。ChannelWriter提供了以下幾個方法:

  • WriteAsync - 異步寫入

  • WaitToWriteAsync - 非阻塞等待,直到有空間可寫入時或Channel關閉時,返回true/false

  • TryWrite - 嘗試寫入

  • Complete - 標記Channel為關閉,并不再寫入數據到該Channel

  • TryComplete - 嘗試標記Channel為關閉。

這幾個方法很容易理解,就不解釋了。

在本文的例子里,我用了:

await?channel.Writer.WriteAsync("New?message");

讀取Channel

使用閱讀器ChannelReader從Channel進行數據的讀取。也提供了幾個方法:

  • ReadAsync - 異步讀取

  • ReadAllAsync - 異步讀取Channel中的所有數據

  • TryRead - 嘗試讀取

  • WaitToReadAsync - 非阻塞等待,直到有數據可讀取或Channel關閉時,返回true/false

不同的消費者模式,會用到不同的讀取方法。這個根據經驗來寫就好。

本文的例子中,我是采用WaitToReadAsync和ReadAsync配合來使用的:

while?(await?ChannelReader.WaitToReadAsync()) {if?(ChannelReader.TryRead(out?var?timeString)){/***/} }

WaitToReadAsync是一個非阻塞等待,在有消息可讀或Channel關閉時,才會喚醒并繼續。

考慮到有多個消費者的情況,有可能別的線程已經進行了讀取,這兒使用TryRead進行讀取操作。

要注意:數據的同步工作是由Channel進行管理的。Channel會確保多個消費者不會讀到相同的數據。Channel同時也管理數據的次序。

示例代碼

今天的示例代碼我放到了Github上。鏈接是文章最后。

這個例子中,我做了三個場景。

首先是Channel。我使用了無限Channel。然后是創建生產者和消費者。數據傳輸過程就簡單化了,生產者只簡單將一個字符串寫入到Channel。消費者也是,簡單等待并從Channel讀取數據字符串,寫入控制臺。

三個場景分別是:

單一生產者/單一消費者

這個例子中,創建了一個生產者和一個消費者。兩者的任務都是并發啟動的。

里面的延時,是用來模擬工作負載的。

多個生產者/單一消費者

這個例子中有兩個生產者。通常在應用中有多個生產者時,我們需要確保生產與單個消費者所能處理的消息數量大致相當,這樣能更好地利用服務器資源。

單一生產者/多個消費者

這個其實是應用中最常見的情況,就是產生消息很快,但處理工作相關較慢,而且工作也更密集。這種情況,實際應用中我們可以通過擴大消費者數量來滿足生產的需求。

總結

最近的項目在做一個大數據的采集,用到了一些Channel的技術。然后發現網上這部分內容很少,就做了個例子,寫了這個文章。

Channel內容本身并不多,但用著很方便,而且實際應用中,比想像的更強大。它可以簡化很多生產者/消費者模式的使用,而且,任務間交換數據,使用Channel會更方便,更直接。

?

示例代碼在:https://github.com/humornif/Demo-Code/tree/master/0033/demo

喜歡就來個三連,讓更多人因你而受益

總結

以上是生活随笔為你收集整理的Dotnet Core下的Channel, 你用了吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。