一个简单的Log类

经常在运行程序时需要在某些地方记录log,之前想用Log4Net,但又感觉要附带一个dll,想要只带一个exe文件运行,干脆自己写个简单的类了。

需要满足的条件:被多个线程调用;时间的准确性不重要,知道先后关系就行;不想阻塞线程,毕竟干活才是主要目的,为了不太在意时间的log而阻塞等待有点不划算。

然后开始:1.需要静态类,默认存储在当前目录下,可指定log文件名;2.需要一个用来写入到文件的方法。

public static class LogWriter
{
   static string logPath ="Log_"+ DateTime.Now.ToString("yyyyMMdd") + ".txt";    
   private static void WriteLine_Helper(string str)
        {
            using (System.IO.StreamWriter writer = new System.IO.StreamWriter(logPath, true))
            {
                writer.WriteLine(DateTime.Now.ToString("yyyy/MM/dd  HH:mm:ss    ") + str);
                writer.Close();
            }
        }
}

然后,直接写的话会存在同时访问的问题,在不使用锁进行阻塞的前提下,这里使用两个List存储消息队列,并用一个bool变量UseList1来标识当前存储到的List,当存储List1的时候,建立线程将List2中的内容写入到log并清除list2中的消息,然后取反UseList1,将消息存储到List2队列,此时将List1中的消息写入log并清除list1中的消息,最后检查list1和list2中是否还有消息,如果有则继续写入。

static List<string> list1 = new List<string>();
static List<string> list2 = new List<string>();
static bool UseList1 = false;
static bool isUsed = false;

public static void WriteLine(string str)     //将消息放进List中
        {
            if (UseList1)    //如果当前正在使用List1写入log,就将消息放入list2
            {
                list2.Add(str);
            }
            else
            {
                list1.Add(str);
            }

            if (!isUsed)    //如果没开启线程,则开启线程
            {
                isUsed = true;
                Thread t = new Thread(WriteList);
                t.Start();
            }
        }
private static void WriteList()   //将list中的消息写入log
        {
            if (UseList1)   //如果正在使用list1,则将list1的消息写入log
            {
                Write(list1);
                list1.Clear();  //list1的消息写入完成后清除list1消息
                UseList1 = false;   //取反UseList1,之后消息写入List2
                Write(list2);   //将list2中的消息写入log
                list2.Clear();   //清除list2中的消息
            }
            else
            {
                Write(list2);
                list2.Clear();
                UseList1 = true;
                Write(list1);
                list1.Clear();
            }
            isClear();   //检查在写入log期间是否有新增消息,如果有则继续写
            isUsed = false;
        }

private static void Write(List<string> list)   //将list中的消息写入log文件
        {
            for (int i = 0; i < list.Count; i++)
            {
                WriteLine_Helper(list[i]);
            }
        }

public static void isClear()   //检查是否list1和list2中是否还有消息未写入
        {
            if (list1.Count>0 || list2.Count>0)
            {
                WriteList();
            }
        }

实践发现写log频率高的时候的确log消息会滞后几秒,应该是频繁建立线程和频繁的打开和关闭文件造成的。可以建立一个线程等待消息,增加一个list计数,当list中消息达到一定数量的时候再打开文件写入log,减少文件的打开和操作次数,不过对于只是偶尔看看状态用的log,不折腾了。。。

猜你喜欢

转载自www.cnblogs.com/Elvis-Luo/p/11470538.html