内存队列使用Channels
我也是copy别人的。
注册的主要方法体里面,我这是后台默默的处理日志。
var filechannel = Channel.CreateBounded<string>(6);
使用了有边界的,因为考虑到一次处理不完那么多。都放内存。内存会造反。
写一个生产者
public class Producer
{
private readonly ChannelWriter<string> _writer;
private readonly DirectoryInfo taskDir;
public Producer(ChannelWriter<string> writer)
{
_writer = writer;
taskDir = new DirectoryInfo(@"D:\logs");
}
public async Task CreateFileTask()
{
while (true)
{
var files = taskDir.GetFiles($"*.log").Where(q => q.CreationTime < DateTime.Now.AddSeconds(3))
.OrderBy(q => q.CreationTime).Take(100).ToList();
foreach (var filename in files)
{
if (await _writer.WaitToWriteAsync())
{
await _writer.WriteAsync(filename.FullName);
}
}
await Task.Delay(500);
}
}
}
消费者
public class Consumer
{
private readonly ChannelReader<string> _reader;
private string key;
public Consumer(ChannelReader<string> reader,string _key)
{
_reader = reader;
key = _key;
}
public async Task ConsumeData()
{
while (await _reader.WaitToReadAsync())
{
if (_reader.TryRead(out var filename))
{
if (!File.Exists(filename))
{
continue;
}
try
{
var text = File.ReadAllText(filename);
if (text.Length == 0)
{
File.Delete(filename);
continue;
}
Console.WriteLine($"{key}:{DateTime.Now}{filename}");
await Task.Delay(5000);
Console.WriteLine($"{key}:{DateTime.Now}{filename}");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
await Task.Delay(50000);
}
//await Task.Delay(500);
}
}
}
}
加入try,catch,是因为出错了。会停止。
主要的调用比如说在一个后台服务里面。
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
var filechannel = Channel.CreateBounded<string>(6);
var producer1 = new Producer(filechannel.Writer);
var consumer1 = new Consumer(filechannel.Reader,"0");
var consumer2 = new Consumer(filechannel.Reader,"1");
var consumer3 = new Consumer(filechannel.Reader,"2");
Task consumerTask1 = consumer1.ConsumeData(); // begin consuming
Task consumerTask2 = consumer2.ConsumeData(); // begin consuming
Task consumerTask3 = consumer3.ConsumeData(); // begin consuming
Task producerTask1 = producer1.CreateFileTask();
await producerTask1.ContinueWith(_ => filechannel.Writer.Complete());
await Task.WhenAll(consumerTask1, consumerTask2, consumerTask3);
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());
}
return Task.CompletedTask;
}
打完收工。水平很糙,主要是记录下。免得自己忘记。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?