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

