利用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 = ; i < ; i++)
{
FileWriteQueue.Get("success").WriteLine(i.ToString());
}
利用BlockingCollection实现生产者和消费者队列,实现写文本的更多相关文章
- 使用事件等待句柄EventWaitHandler 实现生产者、消费者队列
using System; using System.Threading; using System.Collections.Generic; class ProducerConsumerQueue ...
- Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型
Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...
- 利用反射快速给Model实体赋值 使用 Task 简化异步编程 Guid ToString 格式知多少?(GUID 格式) Parallel Programming-实现并行操作的流水线(生产者、消费者) c# 无损高质量压缩图片代码 8种主要排序算法的C#实现 (一) 8种主要排序算法的C#实现 (二)
试想这样一个业务需求:有一张合同表,由于合同涉及内容比较多所以此表比较庞大,大概有120多个字段.现在合同每一次变更时都需要对合同原始信息进行归档一次,版本号依次递增.那么我们就要新建一张合同历史表, ...
- [原创]如何编写多个阻塞队列连接下的多生产者多消费者的Python程序
平常在写程序时,往往会遇到一个需求:在程序的多个阶段都会出现阻塞的可能,因此,这多个阶段就需要并发执行. Python的多线程有一个特点,就是不允许从外部结束一个运行中的线程,这给我们编写代码时带来了 ...
- C# 实现生产者消费者队列
开发过程中经常会碰到这样的场景:需要从一个地方获取一些数据,然后处理数据并将其保存在数据库中. 1 2 3 4 5 6 7 8 9 10 private void FetchData() {} pri ...
- 守护进程,互斥锁,IPC,队列,生产者与消费者模型
小知识点:在子进程中不能使用input输入! 一.守护进程 守护进程表示一个进程b 守护另一个进程a 当被守护的进程结束后,那么守护进程b也跟着结束了 应用场景:之所以开子进程,是为了帮助主进程完成某 ...
- 人生苦短之我用Python篇(队列、生产者和消费者模型)
队列: queue.Queue(maxsize=0) #先入先出 queue.LifoQueue(maxsize=0) #last in fisrt out queue.PriorityQueue( ...
- 用Java写一个生产者-消费者队列
生产者消费者的模型作用 通过平衡生产者的生产能力和消费者的消费能力来提升整个系统的运行效率,这是生产者消费者模型最重要的作用. 解耦,这是生产者消费者模型附带的作用,解耦意味着生产者和消费者之间的联系 ...
- 0032ActiveMQ之java编码实现生产者和消费者操作队列queue
今天学习了入门级的用java编写生产者producer和消费者consumer操作activemq的queue队列,为了之后复习回顾,现做整理如下: maven工程的搭建此处不再讲解,在maven工程 ...
随机推荐
- Python实例---CRM管理系统分析180331
注意:一个项目基本都设计增删改查,且第一个需要做的就是设计表结构 思维导图: 组件使用: Django + bootStrap + Jquery 数据库表结构设计: 外键关联: 2种方式, ...
- redis几种数据类型以及使用场景
1. string类型 string为最简单类型,一个key对应一个value set mykey "wangzai" ##设置key,第二次赋值会直接覆盖之前的 setnx my ...
- (转)Matlab矩阵的简单操作
转自:http://blog.sina.com.cn/s/blog_6264e23a0100veeq.html
- November 24th 2016 Week 48th Thursday
All the bright precious things fade so fast. 所有的光鲜靓丽都敌不过时间. What is permanent? Thoughts and ideas. P ...
- Alpha 冲刺报告(6/10)
Alpha 冲刺报告(6/10) 队名:洛基小队 峻雄(组长) 已完成:实现角色的移动. 明日计划:关于角色的属性设计. 剩余任务:角色的属性脚本 困难:角色的属性以及具体的编码 ---------- ...
- python处理数据(二)
处理PDF文件 PyPDF2简介 作为 PDF 工具包构建的纯 python 库. 它可以:提取文档信息(标题,作者,... ...)一页一页地分割文件一页一页地合并文件裁剪页面将多个页面合并成一个页 ...
- python多进程(一)
操作系统进程 Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊.普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复 ...
- Angular 星级评分组件
一.需求演变及描述: 1. 有一个“客户对公司的总体评价”的字段(evalutation).字段为枚举类型,0-5,对应关系为:0-暂无评价,1-很差,2-差,3-一般,4-好,5-很好 2. 后来需 ...
- C++ Primer Plus 第15章 友元、异常和其它
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/chudaxiakkk/article/details/30502807 第15章 友元.异常和其它 ...
- 1833. [ZJOI2010]数字计数【数位DP】
Description 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. Input 输入文件中仅包含一行两个整数a.b,含义如上所述. Output 输出文 ...