• 利用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());
                }
  • 相关阅读:
    ZT 二叉树先序,中序,后序遍历非递归实现
    二叉树的遍历(一)
    Z :彻底了解指针数组,数组指针以及函数指针 [复
    ZT 复杂的函数指针例子分析 2008
    D:hunting2014小题目字符串倒序
    本周实验的PSP0过程文档
    构建之法阅读笔记02
    第二周学习进度
    实现自动生成30道四则运算题目(2)
    实现自动生成30道四则运算题目
  • 原文地址:https://www.cnblogs.com/mldcy/p/8331619.html
Copyright © 2020-2023  润新知