当前位置: 代码迷 >> .NET相关 >> 【.net】创造属于自己的log组件——改进版
  详细解决方案

【.net】创造属于自己的log组件——改进版

热度:178   发布时间:2016-04-24 02:38:52.0
【.net】创建属于自己的log组件——改进版

在上一篇随笔中,建立了一个自己的Log简单日志记录类  

可是在众多园友的提点下,对于线程,阻塞,资源竞争等都没有仔细的去了解

在这版的改进中,我们新加了线程操作,线程等待,以及多层的错误捕获。【不知道有什么用可是潜意识叫我加上】

这些改进用于——作为一个本分的Log,绝对不影响主线程的流程不阻塞,同时能应对多个日志写入的要求,且避免资源的竞争。充分利用cpu的优势,让Log稳定的记录。

 

改进之后的代码

【感谢@Leandro的建议,再次修改之后的代码】

using System;using System.ComponentModel;using System.IO;using System.Threading;using System.Threading.Tasks;namespace CustomerLog{    /// <summary>    /// 保存日志    /// </summary>    public class Loghelper    {        private static Mutex _mutex;        static Loghelper()        {            _mutex = new Mutex();        }        #region 公开线程写入日志        /// <summary>        /// 消息日志记录        /// </summary>        /// <param name="message">消息</param>        public void Log(string message)        {            try            {                new Task(() => Writelog(message)).Start();            }            catch            {                // ignored            }        }        /// <summary>        /// 错误日志记录        /// </summary>        /// <param name="ex">错误</param>        public void Log(Exception ex)        {            try            {                new Task(() => WriteBuglog(ex)).Start();            }            catch            {                // ignored            }        }        #endregion        #region 日志分类        /// <summary>        /// 保存普通日志        /// </summary>        /// <param name="message"></param>        private bool Writelog(string message)        {            string logContent = string.Format("[{0}] =>{1}", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"), message);            return SetFile(@"Log.txt", logContent);        }        /// <summary>        /// 保存错误信息日志        /// </summary>        /// <param name="ex"></param>        private bool WriteBuglog(Exception ex)        {            var logContent = string.Format("[{0}]错误发生在:{1},\r\n 内容:{2}",                DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"), ex.Source, ex.Message);            logContent += string.Format("\r\n  跟踪:{0}", ex.StackTrace);            return SetFile(@"BugLog.txt", logContent);        }        #endregion        #region 通用操作        /// <summary>        /// 标准化写入过程,继承之后可自定义写入内容        /// 默认保存在debug目录的Log目录下        /// </summary>        /// <param name="filename">文件名</param>        /// <param name="logContent">写入内容</param>        private static bool SetFile(string filename, string logContent)        {            _mutex.WaitOne();            try            {                Isexist(); // 判断Log目录是否存在                string errLogFilePath = Environment.CurrentDirectory + @"\Log\" + filename.Trim();// 获取当前目录地址                StreamWriter sw;                if (!File.Exists(errLogFilePath))                {                    FileStream fs1 = new FileStream(errLogFilePath, FileMode.Create, FileAccess.Write);                    sw = new StreamWriter(fs1);                }                else                {                    sw = new StreamWriter(errLogFilePath, true);                }                sw.WriteLine(logContent);                sw.Flush();                sw.Close();                return true;            }            catch            {                // 忽略错误                return false;            }            finally            {                _mutex.ReleaseMutex();            }        }        // 判断是否存在日志文件        private static void Isexist()        {            string path = Environment.CurrentDirectory + @"\Log\";            if (!File.Exists(path))            {                Directory.CreateDirectory(path);            }        }        #endregion    }}

 

在新的代码中取消了静态的方法,在类初始化的时候实例一个控制线程的控制器。

 

OK修改过后的就这个了。有疑问的希望广大园友能提出来,大家共同学习改进。

 

4楼编程学习
你这看起髙大上,估计性能并不高。首先重打开关闭流,其次还用了一把大锁
3楼皮蛋#178;#186;#185;5
记录一次就开一个线程?
Re: 董小保
@皮蛋#178;#186;#185;5,我想,作为一个路人般的Log组件,第一要务就是不影响主线程的流畅度,且足够的简单,利用多线程,可以把Log提交到clr的运行池里面,控制操作的开关,让Log线程逐个操作文件,不然主线程阻塞。,,我是这么想的,不知道前辈有什么好的想法,交流交流
2楼Leandro
小建议:异步写日志的时候改用Task 异步任务来代替Thread显示的线程开启。
Re: 董小保
@Leandro,谢谢建议,已采用。task可以更好的利用cpu的多核计算。,非常感谢。
1楼洋小洋
SetFile 那个方法里没必要加锁 把文件设置成共享就好了
Re: 董小保
@洋小洋,不加锁会不会使得文件流打开的时候出错?造成线程的竞争?
  相关解决方案