当前位置:  编程技术>.net/c#/asp.net

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

    来源: 互联网  发布时间:2014-10-31

    本文导语:  一般在实际项目的开发中,会要求涉及日志记录的问题,比较常用的有Log4Net,NLog等几个,而小项目小工具的话,则无需费此大驾。而譬如串口开发的话,需要记录串口过来的数据等等,这时候就要考虑日志记录上线程的问题...

一般在实际项目的开发中,会要求涉及日志记录的问题,比较常用的有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();
      }
    }
  }
}

代码运行效果如下所示:

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


    
 
 

您可能感兴趣的文章:

  • c#通过委托delegate与Dictionary实现action选择器代码举例
  • C#实现获取枚举中元素个数的方法
  • C#实现自定义双击事件
  • C#键盘输入回车键实现点击按钮效果的方法
  • C#实现获取一年中是第几个星期的方法
  • C#实现Datatable排序的方法
  • C#实现装箱与拆箱操作简单实例
  • 解决C#中WebBrowser的DocumentCompleted事件不执行的实现方法
  • C#下实现创建和删除目录的实例代码
  • 使用C#实现在屏幕上画图效果的代码实例
  • C#实现过滤html标签并保留a标签的方法
  • c#实现TextBox只允许输入数字
  • C# Winform 整个窗口拖动的实现代码
  • c# ListView实现双击Item事件的变通方法
  • C#实现随鼠标移动窗体实例
  • C#中的FileUpload 选择后的预览效果具体实现
  • C# 窗体隐藏及任务管理器中禁止关闭的实现代码
  • C#的锯齿数组以及C++实现代码
  • C#格式化文件大小的实现代码
  • C#怎样才能实现窗体最小化到托盘呢?
  • C# char类型字符转换大小写的实现代码
  • 如何实现一个线程组内多线程的非同不执行,即一个线程执行完毕后再执行下一个线程???
  • socket实现多文件并发传输,求助多线程实现问题?
  • 如何实现这样的API,可同时被不同的进程/线程使用,但是又不区分进程/线程?
  • **********如何根据线程的handle,来实现挂起指定线程********
  • C++实现CreatThread函数主线程与工作线程交互的方法
  • 如何实现监控线程?
  • 不用 signal,如何实现线程的休眠与唤醒
  • 怎样实现:任意一个线程终止,就终止整个进程?
  • 我需要一个模型,在 LINUX C 下。实现线程间的控制,执行,阻塞,再执行。。。。。不知道如何实现。
  • 如何实现多线程下的文件锁?
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • python搭建简易服务器分析与实现
  • c#入门之实现简易存款利息计算器示例
  • Android图片翻转动画简易实现代码
  • Android音频录制MediaRecorder之简易的录音软件实现代码
  • 通过javascript实现DIV居中,兼容各浏览器版本
  • interface 到底有什么用???实现接口,怎么实现??
  • Python GUI编程:tkinter实现一个窗口并居中代码
  • 怎么用Jsp实现在页面实现树型结构?
  • 通过javascript库JQuery实现页面跳转功能代码
  • windows 下的PortTunnel 在linux下怎么实现?或者相应的已经实现的软件?端口映射
  • sharepoint 2010 使用STSNavigate函数实现文件下载举例
  • 网站重定向用C语言实现iptables,ACL实现
  • php实现socket实现客户端和服务端数据通信源代码
  • 在linux下如何编程实现nslookup命令实现的IP地址和域名互相转换的功能?
  • flash AS3反射实现(describeType和getDefinitionByName)
  • 求在freebsd+Squid下实现pc上网的透明代理的实现方法!给出具体配置方法的高分谢!
  • boost unordered_map和std::list相结合的实现LRU算法
  • linux下如实现与window下的驱动器实现文件共享??
  • 使用java jdk中的LinkedHashMap实现简单的LRU算法
  • qt如何实现:操作键盘实现数据的滚动?
  • iphone cocos2d 精灵的动画效果(图片,纹理,帧)CCAnimation实现
  • 我想用APPLET实现读取客户端的图片文件,该如何实现?
  • c语言判断某一年是否为闰年的各种实现程序代码
  • PING是用TCP,还是用UDP来实现的?或是采用其它协议实现的?
  • html<pre>标签自动换行实现方法
  • ejb-ql只能 like '?%' 么?我想实现模糊查寻,想实现 like'%?%' 怎么办??


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3