在C#中,Channel
类是.NET Core
提供的一种新的生产者消费者模型。Channel
类位于System.Threading.Channels
命名空间下,它提供了一种异步的消息传递机制,可以用来在生产者和消费者之间传递数据。
Channel
类主要用于以下场景:
Channel
类。Channel
类提供了一种线程安全的方式来传递数据,可以避免在多线程环境中出现的数据竞争问题。Channel
类来异步地处理数据。C#Channel<string> channel = Channel.CreateUnbounded<string>();
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 写
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnTest_Click(object sender, EventArgs e)
{
Random random = new Random();
Task.Run(() =>
{
var writer = channel.Writer;
while (true)
{
writer.WriteAsync(random.Next(1, 100).ToString());
System.Threading.Thread.Sleep(1000);
}
});
}
/// <summary>
/// 读
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnRead_ClickAsync(object sender, EventArgs e)
{
var reader = channel.Reader;
Task.Run(async () =>
{
while (await reader.WaitToReadAsync())
{
while (reader.TryRead(out var message))
{
this.Invoke(() =>
{
lsbData.Items.Add(message);
});
}
}
});
}
关闭 channel
C#private void btnStop_Click(object sender, EventArgs e)
{
//关闭Channel
channel.Writer.Complete();
}
C#public partial class Form1 : Form
{
Channel<string> channel = Channel.CreateUnbounded<string>();
public Form1()
{
InitializeComponent();
}
private async Task ListFilesAsync(string directoryPath
, ChannelWriter<string> writer)
{
await Task.Run(async () =>
{
foreach (var file in Directory.EnumerateFiles(directoryPath))
{
await writer.WriteAsync(file);
}
foreach (var directory in Directory.EnumerateDirectories(directoryPath))
{
await ListFilesAsync(directory, writer);
}
});
}
private async Task AddFilesToListBoxAsync(ChannelReader<string> reader, ListBox listBox)
{
await foreach (var file in reader.ReadAllAsync())
{
listBox.Invoke((Action)(() => listBox.Items.Add(file)));
await Task.Delay(1);
}
}
private async void btnRead_ClickAsync(object sender, EventArgs e)
{
var writer = channel.Writer;
var reader = channel.Reader;
// 开始做生产消费
var producer = ListFilesAsync(@"D:\BaiduSyncdisk\11Test", writer);
var consumer = AddFilesToListBoxAsync(reader, lsFiles);
// 等待两个都完成
await Task.WhenAll(producer, consumer);
}
}
注:使用await Task.Delay(1);
来避免UI冻结。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!