.NET?中?Channel?類簡單使用方法
Channel 是干什么的
The System.Threading.Channels namespace provides a set of synchronization data structures for passing data between producers and consumers asynchronously. The library targets .NET Standard and works on all .NET implementations.
Channels are an implementation of the producer/consumer conceptual programming model.
以上是微軟官方的解釋 channels。用中文說的話就是這個類提供了在生產(chǎn)者跟消費者之間異步傳統(tǒng)數(shù)據(jù)的能力,簡單來說可以認為是一個內(nèi)存消息隊列。
示例 1
下面是一個簡單的示例,說明如何使用 Channel 類來創(chuàng)建一個生產(chǎn)者-消費者模型:
static async Task Main(string[] args) { var channel = Channel.CreateUnbounded<int>(); var producer = Task.Run(async () => { for (int i = 0; i < 10; i++) { await channel.Writer.WriteAsync(i); await Task.Delay(1000); // 模擬生產(chǎn)者需要一些時間來生成數(shù)據(jù) } channel.Writer.Complete(); }); var consumer = Task.Run(async () => { await foreach (var item in channel.Reader.ReadAllAsync()) { Console.WriteLine($"消費者接收到: {item}"); } }); await Task.WhenAll(producer, consumer); }
在這個例子中,我們創(chuàng)建了一個無界的通道,然后創(chuàng)建了兩個任務(wù),一個是生產(chǎn)者,一個是消費者。生產(chǎn)者每秒生成一個數(shù)字,然后寫入通道。消費者從通道中讀取數(shù)據(jù)并打印出來。當(dāng)生產(chǎn)者完成寫入后,它會調(diào)用 channel.Writer.Complete() 來通知消費者沒有更多的數(shù)據(jù)可以讀取。
示例 2
你可以使用 Channel.CreateBounded(capacity) 方法來創(chuàng)建一個有界的通道,其中 capacity 參數(shù)指定了通道的容量。當(dāng)通道滿時,嘗試寫入的操作將會阻塞,直到有空間可用。
static async Task Main(string[] args) { var channel = Channel.CreateBounded<int>(5); // 創(chuàng)建一個容量為5的有界通道 var producer = Task.Run(async () => { for (int i = 0; i < 10; i++) { await channel.Writer.WriteAsync(i); Console.WriteLine($"生產(chǎn)者生成了: {i}"); await Task.Delay(1000); // 模擬生產(chǎn)者需要一些時間來生成數(shù)據(jù) } channel.Writer.Complete(); }); var consumer = Task.Run(async () => { await foreach (var item in channel.Reader.ReadAllAsync()) { Console.WriteLine($"消費者接收到: {item}"); await Task.Delay(2000); // 模擬消費者需要一些時間來處理數(shù)據(jù) } }); await Task.WhenAll(producer, consumer); }
在這個例子中,我們創(chuàng)建了一個容量為5的有界通道。生產(chǎn)者每秒生成一個數(shù)字,然后寫入通道。消費者從通道中讀取數(shù)據(jù)并打印出來,但消費者處理數(shù)據(jù)的速度比生產(chǎn)者慢,所以當(dāng)通道滿時,生產(chǎn)者的 WriteAsync 操作將會阻塞,直到消費者讀取了一些數(shù)據(jù),使得通道有空間可用。
示例 3
下面是一個示例,展示了如何在多個生產(chǎn)者和消費者之間共享一個通道:
static async Task Main(string[] args) { var channel = Channel.CreateUnbounded<int>(); // 創(chuàng)建兩個生產(chǎn)者 var producer1 = Produce(channel.Writer, id: 1); var producer2 = Produce(channel.Writer, id: 2); // 創(chuàng)建兩個消費者 var consumer1 = Consume(channel.Reader, id: 1); var consumer2 = Consume(channel.Reader, id: 2); // 等待所有生產(chǎn)者和消費者完成 await Task.WhenAll(producer1, producer2, consumer1, consumer2); } static async Task Produce(ChannelWriter<int> writer, int id) { for (int i = 0; i < 10; i++) { await writer.WriteAsync(i); Console.WriteLine($"生產(chǎn)者{id}生成了: {i}"); await Task.Delay(1000); // 模擬生產(chǎn)者需要一些時間來生成數(shù)據(jù) } writer.Complete(); } static async Task Consume(ChannelReader<int> reader, int id) { await foreach (var item in reader.ReadAllAsync()) { Console.WriteLine($"消費者{id}接收到: {item}"); await Task.Delay(2000); // 模擬消費者需要一些時間來處理數(shù)據(jù) } }
在這個例子中,我們創(chuàng)建了兩個生產(chǎn)者和兩個消費者,它們都共享同一個通道。這是一個非常重要使用模式。因為當(dāng)我們使用消息隊列的時候往往會有多個生產(chǎn)者跟多個消費者。我們可以通過控制生產(chǎn)者生產(chǎn)的速度來控制推入隊列的數(shù)據(jù)量。我們還可以通過控制消費者的數(shù)量來控制消費數(shù)據(jù)的速度,從而來調(diào)節(jié)系統(tǒng)的流量,達到消峰填谷的作用。
總結(jié)
Channel 類是 .NET CORE 3.0 后新加入的類。為我們提供了便利的生產(chǎn)者/消費者模式實現(xiàn)方案。相當(dāng)于是一個進程內(nèi)的內(nèi)存隊列,而且它沒有持久化,純內(nèi)存操作,性能是非常非常高的。當(dāng)我們面對真正的高并發(fā)的時候可以為我們的系統(tǒng)提供吞吐量。當(dāng)然代價是內(nèi)存跟放棄一些實時性。
到此這篇關(guān)于.NET 中 Channel 類簡單使用的文章就介紹到這了,更多相關(guān).NET Channel 類使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
asp.net core常見的4種數(shù)據(jù)加密算法
這篇文章主要介紹了asp.net core常見的4種數(shù)據(jù)加密算法,文中代碼非常詳細,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06把jQuery的each(callback)方法移植到c#中
jQuery中使用each(callback)方法可以很方便的遍歷集合,如2008-03-03asp.net core 3.0中使用swagger的方法與問題
這篇文章主要給大家介紹了關(guān)于asp.net core 3.0中使用swagger的方法與遇到的一些問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者使用asp.net core 3.0具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10asp.net XMLHttpRequest實現(xiàn)用戶注冊前的驗證
用戶注冊前的驗證,提高用戶體驗。2009-10-10asp.net?web?api2設(shè)置默認啟動登錄頁面的方法
這篇文章主要介紹了asp.net?web?api2設(shè)置默認啟動登錄頁面的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09ASP.NET Core應(yīng)用中與第三方IoC/DI框架的整合
ASP.NET Core應(yīng)用中,針對第三方DI框架的整合可以通過在定義Startup類型的ConfigureServices方法返回一個ServiceProvider來實現(xiàn)。但是并不是那么容易的,下面通過實例給大家分享一下2017-04-04