当前位置:
首页 > Python基础教程 >
-
C#教程之利用BlockingCollection实现生产者和消费者队
最近开发几个小项目,需要把结果写到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()); }
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式