栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C# > C#教程

C#实现线程安全的简易日志记录方法

C#教程 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#实现线程安全的简易日志记录方法

一般在实际项目的开发中,会要求涉及日志记录的问题,比较常用的有Log4Net,NLog等几个,而小项目小工具的话,则无需费此大驾。而譬如串口开发的话,需要记录串口过来的数据等等,这时候就要考虑日志记录上线程的问题。对此,为了方便后续使用,封装了下代码:

using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;

namespace CSharpUtilHelpV2
{
  /// 
  /// 日志类型枚举
  /// 
  public enum LogType
  {
    /// 
    /// 一般输出
    /// 
    Trace,
    /// 
    /// 警告
    /// 
    Warning,
    /// 
    /// 错误
    /// 
    Error,
    /// 
    /// SQL
    /// 
    SQL
  }
  /// 
  /// 基于.NET 2.0日志工具类
  /// 
  public class LogToolV2
  {
    private static readonly Thread LogTask;
    private static readonly ThreadSafeQueueV2 LogColQueue;//自定义线程安全的Queue
    private static readonly object SyncRoot;
    private static readonly string FilePath;
    private static readonly long BackFileSize_MB = 2;//超过2M就开始备份日志文件
    static LogToolV2()
    {
      SyncRoot = new object();
      FilePath = AppDomain.CurrentDomain.SetupInformation.Applicationbase + "Log\";
      LogTask = new Thread(WriteLog);
      LogColQueue = new ThreadSafeQueueV2();
      LogTask.Start();
      Debug.WriteLine("Log Start......");
    }
    /// 
    /// 记录日志
    /// 
    /// 日志内容
    public static void Log(string msg)
    {
      string _msg = string.Format("{0} : {2}", DateTime.Now.ToString("HH:mm:ss"), msg);
      LogColQueue.Enqueue(msg);
    }
    /// 
    /// 记录日志
    /// 
    /// 日志内容
    /// 日志类型
    public static void Log(string msg, LogType type)
    {
      string _msg = string.Format("{0} {1}: {2}", DateTime.Now.ToString("HH:mm:ss"), type, msg);
      LogColQueue.Enqueue(_msg);
    }
    /// 
    /// 记录日志
    /// 
    /// 异常
    public static void Log(Exception ex)
    {
      if (ex != null)
      {
 string _newline = Environment.newline;
 StringBuilder _builder = new StringBuilder();
 _builder.AppendFormat("{0}: {1}{2}", DateTime.Now.ToString("HH:mm:ss"), ex.Message, _newline);
 _builder.AppendFormat("{0}{1}", ex.GetType(), _newline);
 _builder.AppendFormat("{0}{1}", ex.Source, _newline);
 _builder.AppendFormat("{0}{1}", ex.TargetSite, _newline);
 _builder.AppendFormat("{0}{1}", ex.StackTrace, _newline);
 LogColQueue.Enqueue(_builder.ToString());
      }
    }
    private static void WriteLog()
    {
      while (true)
      {
 if (LogColQueue.Count() > 0)
 {
   string _msg = LogColQueue.Dequeue();
   Monitor.Enter(SyncRoot);
   if (!CreateDirectory()) continue;
   string _path = string.Format("{0}{1}.log", FilePath, DateTime.Now.ToString("yyyyMMdd"));
   Monitor.Exit(SyncRoot);
   lock (SyncRoot)
   {
     if (CreateFile(_path))
ProcessWriteLog(_path, _msg);//写入日志到文本
   }
   ProcessBackLog(_path);//日志备份
 }
      }
    }
    private static void ProcessBackLog(string path)
    {
      lock (SyncRoot)
      {
 if (FileToolV2.GetMBSize(path) > BackFileSize_MB)
 {
   FileToolV2.CopyToBak(path);
 }
      }
    }
    private static void ProcessWriteLog(string path, string msg)
    {
      try
      {
 StreamWriter _sw = File.AppendText(path);
 _sw.WriteLine(msg);
 _sw.Flush();
 _sw.Close();
      }
      catch (Exception ex)
      {
 Debug.WriteLine(string.Format("写入日志失败,原因:{0}", ex.Message));
      }
    }
    private static bool CreateFile(string path)
    {
      bool _result = true;
      try
      {
 if (!File.Exists(path))
 {
   FileStream _files = File.Create(path);
   _files.Close();
 }
      }
      catch (Exception)
      {
 _result = false;
      }
      return _result;
    }
    private static bool CreateDirectory()
    {
      bool _result = true;
      try
      {
 if (!Directory.Exists(FilePath))
 {
   Directory.CreateDirectory(FilePath);
 }
      }
      catch (Exception)
      {
 _result = false;
      }
      return _result;
    }

  }
}

测试代码如下:

using CSharpUtilHelpV2;
using System;
using System.Diagnostics;
using System.Threading;

namespace LogUtilHelpV2Test
{
  class Program
  {
    static void Main(string[] args)
    {
      try
      {
 Debug.WriteLine("-------------");
 Action _writeLog = delegate()
 {
   for (int i = 0; i < 10000; i++)
     LogToolV2.Log(Guid.NewGuid().ToString(), LogType.Trace);
 };
 Thread _wireteLogTask1 = new Thread(new ThreadStart(_writeLog));
 _wireteLogTask1.Start();

 Thread _wireteLogTask2 = new Thread(new ThreadStart(_writeLog));
 _wireteLogTask2.Start();

 //throw new Exception("test  aaa bb cc");
      }
      catch (Exception ex)
      {
 LogToolV2.Log(ex);
 Console.WriteLine(ex.Message.Trim());
      }
      finally
      {
 Console.WriteLine("ok");
 Console.ReadLine();
      }
    }
  }
}

代码运行效果如下所示:

感兴趣的读者可以自己测试运行一下,希望能对大家起到一点帮助!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/126341.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号