zoukankan      html  css  js  c++  java
  • 写入日志时并发及加锁的思考

    在简单的项目架构搭建中经常会考虑日志记录的问题,这难免也不可避免许多附带问题的产生。最近我也遇到了相同的事,问题大概有以下两点:

    1.并发处理

    2.如果使用加锁的方式,如何处理性能上的问题

    先展示第一种方式,我直接用加锁的方式来处理,这样就可避免在多个用户同时需要写入一个相同日志文件时产生的读写冲突

      lock ("ExceptionLog")
                {
                    File.AppendAllText(@"C:UsersThinkDesktoplog.txt", msg + "
    +------------------
    ");
                }

    这样能有效的解决之前所提的并发产生的读写冲突,但这样也就会因此衍生一个新的问题。加锁之后万一读取过程出现了错误,这样会延长其他用户等待写入的时间,性能上也就会跟着受影响了。

    庆幸的是微软提供我们一个消息队列的概念,能较好的解决用户等待的问题。做法其实也不难,把所有的错误信息都放到内存中去,再从内存中拿信息。这是一个很简单并且有效的解决方案,突然想到当时面试时有一次问我怎么处理消息推送时网络中断的问题了,当时回答的加锁确实不是最有效的办法。看以下代码:

    public static void WriteLog()
            {
    
                
                //解决让用户等待的问题
                ThreadPool.QueueUserWorkItem(s =>
                {
                    while (true)
                    {
                        if (ErrorQueue.Count > 0)
                        {
                            //从队列里去读取信息
                            string msg = ErrorQueue.Dequeue();
                            File.AppendAllText(@"C:UsersThinkDesktoplog.txt", msg + "
    +------------------
    ");                       
                        }
                        Thread.Sleep(1000);//1秒读一次
                    }
                });
               
            }
            /// <summary>
            /// 把错误信息加到内存,再从内存拿信息
            /// </summary>
            private static Queue<string> ErrorQueue = new Queue<string>();
            public static void AddError(string msg) 
            {
                ErrorQueue.Enqueue(msg);
            }

    随后在 Global 文件中开启一个后台线程,进行日志的保存操作

     LogHelper.WriteLog();
  • 相关阅读:
    86. Partition List
    2. Add Two Numbers
    55. Jump Game
    70. Climbing Stairs
    53. Maximum Subarray
    64. Minimum Path Sum
    122. Best Time to Buy and Sell Stock II
    以场景为中心的产品设计方法
    那些产品经理犯过最大的错
    Axure教程:如何使用动态面板?动态面板功能详解
  • 原文地址:https://www.cnblogs.com/byvar/p/4906729.html
Copyright © 2011-2022 走看看