利用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工程 ...
随机推荐
- Linux 重定向详解
常用的命令展示 >: 输出重定向 没有会创建文件echo hello > h.txt 也可以清空文件 >h.txt >>: ...
- idea指定SpringBoot启动.properties文件
比如我的项目下有2个.properties文件,一个是application.properties,一个是application-local.properties,在本地的时候想指定用applicat ...
- BlockingQueue笔记
Concurrent包中的BlockingQueue很好的解决了多线程中如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利. 通过一个共享 ...
- 如何确定PHP CLI 的php.ini文件的位置
当我们安装扩展时,可能需要手动配置php.ini文件,把扩展加进去,所以要确认PHP CLI的php.ini文件的位置.可以运行php --ini查找PHP CLI的ini文件位置,结果类似如下(各个 ...
- css3实现 依次出现三个点(一般用于提示加载中。。。 提交中。。。)
<a href="javascript:" class="login">登录中<span class="dotting"& ...
- DSU on Tree浅谈
DSU on tree 在之前的一次比赛中,学长向我们讲了了这样一个神奇的思想:DSU on tree(树上启发式合并),看上去就非常厉害--但实际上是非常暴力的一种做法;不过暴力只是看上去暴力,它在 ...
- CentOs7.2编译安装Nginx服务器
1. 安装nginx依赖 首先安装nginx的依赖 yum install gcc gcc-c++ openssl openssl-devel cyrus-sasl-md5 2,创建nginx用户 如 ...
- 初探tp
现在对前端的要求越来越高了 基本上身为一个前端人员需要会一种后台语言,于是选择了当下流行的php.因为是自学对我这个不怎么懂代码的人来说还是有点难度的. 1.先看看thinkphp的目录结构 1 ├ ...
- BZOJ1444:[JSOI2009]有趣的游戏(AC自动机,矩阵乘法)
Description Input 注意 是0<=P, n , l, m≤ 10. Output Sample Input input 1 3 2 2 1 2 1 2 AB BA AA inpu ...
- JS应该放在什么位置?
(1)放在底部,虽然放在底部照样会阻塞所有呈现,但不会阻塞资源下载 (2)如果嵌入JS放在head中,请把嵌入JS放在CSS头部 (3)使用defer(只支持IE) (4)不要在嵌入的JS中调用运行时 ...