-
C#教程之C#教程之利用BlockingCollection实现生产者和消费者队
本站最新发布 C#从入门到精通
试听地址 https://www.xin3721.com/eschool/CSharpxin3721/
试听地址 https://www.xin3721.com/eschool/CSharpxin3721/
最近开发几个小项目,需要把结果写到txt文件里面,并且按照时间进行分文件,由于对于效率要求较高,所以采用 生产者和消费者 模型来进行写出文本,线程中只需要添加队列就立即返回,而不需要等待写文件的时间
感谢@cnc的指正,在Task中判断了日期但是没有把新一天的日期赋值,确实是我的疏忽,再次感谢
public class WriteItem : IDisposable { public string Filename { get; private set; } public Encoding Encode { get; } public bool Append { get; } public bool TimeName { get; } private StreamWriter _writer; private readonly BlockingCollection<string> _blocking = new BlockingCollection<string>(); public void Write(string msg) { _blocking.Add(msg); } public void WriteLine(string msg) { Write(msg + Environment.NewLine); } public WriteItem(string filename, Encoding encode, bool append = true, bool timeName = false) { Filename = filename; Encode = encode; Append = append; TimeName = timeName; if (timeName && string.IsNullOrEmpty(Path.GetExtension(filename))) { this.Filename = Path.Combine(this.Filename, DateTime.Now.ToString("yyyy-MM-dd") + ".txt"); } var dir = Path.GetDirectoryName(this.Filename); Directory.CreateDirectory(dir ?? throw new InvalidOperationException()); _writer = new StreamWriter(this.Filename, this.Append, this.Encode) { AutoFlush = true }; Task.Factory.StartNew(() => { foreach (var s in _blocking.GetConsumingEnumerable()) { if (TimeName) { var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(this.Filename); var nowDay = DateTime.Now.ToString("yyyy-MM-dd").ToString(); if (fileNameWithoutExtension != nowDay) { _writer.Dispose(); this.Filename = Path.Combine(Path.GetDirectoryName(this.Filename), nowDay + ".txt"); _writer = new StreamWriter(this.Filename, this.Append, this.Encode) { AutoFlush = true }; } } _writer.Write(s); } }, TaskCreationOptions.LongRunning); } public void Dispose() { _writer?.Dispose(); _blocking?.Dispose(); } }
然后再写了个字典来维护:
public class FileWriteQueue { private static readonly Dictionary<string, WriteItem> Dictionary = new Dictionary<string, WriteItem>(); public static void AddOrUpdate(string key, WriteItem item) { if (Dictionary.ContainsKey(key)) { Dictionary[key].Dispose(); Dictionary[key] = item; } else { Dictionary.Add(key, item); } } public static WriteItem Get(string key) { return Dictionary[key]; } }
在实际使用添加WirteItem,设置好输出目录就行了:
FileWriteQueue.AddOrUpdate("success",new WriteItem(Path.Combine("结果","成功"),Encoding.Default,true,true)); FileWriteQueue.AddOrUpdate("error", new WriteItem(Path.Combine("结果", "失败"), Encoding.Default, true, true)); for (int i = 0; i < 1000; i++) { FileWriteQueue.Get("success").WriteLine(i.ToString()); }
栏目列表
最新更新
如何使用OS模块中的stat方法
Python os 模块
seek() 方法
python打开文件实例1
Python写入文件
什么是流?
文件操作如何进制逐行读取
Python相对路径
with创建临时运行环境
Python文件操作
.Net Standard(.Net Core)实现获取配置信息
Linux PXE + Kickstart 自动装机
Shell 编程 基础
Shell 编程 条件语句
CentOS8-网卡配置及详解
Linux中LVM逻辑卷管理
1.数码相框-相框框架分析(1)
Ubuntu armhf 版本国内源
Linux中raid磁盘阵列
搭建简易网站
access教程之Access简介
mysql 安装了最新版本8.x版本后的报错:
Mysql空间数据&空间索引(spatial)
如何远程连接SQL Server数据库的图文教程
复制SqlServer数据库的方法
搜索sql语句
sql中返回参数的值
sql中生成查询的模糊匹配字符串
数据定义功能
数据操作功能