当前位置: 移动技术网 > IT编程>开发语言>c# > C#实现线程安全的简易日志记录方法

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

2019年07月18日  | 移动技术网IT编程  | 我要评论
一般在实际项目的开发中,会要求涉及日志记录的问题,比较常用的有log4net,nlog等几个,而小项目小工具的话,则无需费此大驾。而譬如串口开发的话,需要记录串口过来的数据

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

using system;
using system.diagnostics;
using system.io;
using system.text;
using system.threading;

namespace csharputilhelpv2
{
  /// <summary>
  /// 日志类型枚举
  /// </summary>
  public enum logtype
  {
    /// <summary>
    /// 一般输出
    /// </summary>
    trace,
    /// <summary>
    /// 警告
    /// </summary>
    warning,
    /// <summary>
    /// 错误
    /// </summary>
    error,
    /// <summary>
    /// sql
    /// </summary>
    sql
  }
  /// <summary>
  /// 基于.net 2.0日志工具类
  /// </summary>
  public class logtoolv2
  {
    private static readonly thread logtask;
    private static readonly threadsafequeuev2<string> 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<string>();
      logtask.start();
      debug.writeline("log start......");
    }
    /// <summary>
    /// 记录日志
    /// </summary>
    /// <param name="msg">日志内容</param>
    public static void log(string msg)
    {
      string _msg = string.format("{0} : {2}", datetime.now.tostring("hh:mm:ss"), msg);
      logcolqueue.enqueue(msg);
    }
    /// <summary>
    /// 记录日志
    /// </summary>
    /// <param name="msg">日志内容</param>
    /// <param name="type">日志类型</param>
    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);
    }
    /// <summary>
    /// 记录日志
    /// </summary>
    /// <param name="ex">异常</param>
    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();
      }
    }
  }
}

代码运行效果如下所示:

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

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网