处理异步日志写入的更好方法

时间:2012-10-23 06:09:47

标签: c# .net multithreading file-io

public static class LogWriter
{
    private static ReaderWriterLockSlim writeLock = new ReaderWriterLockSlim();
    public static void WriteExceptionLog(string content)
    {
        #if DEBUG
        MessageBox.Show(content);
        #endif
        WriteLog(content, Constant.EXCEPTION_LOG_PATH);
    }
    public static void WriteLog(string content, string path)
    {
        try
        {
            writeLock.EnterWriteLock();
            string directory = Path.GetDirectoryName(path);
            if (!Directory.Exists(Path.GetDirectoryName(directory)))
                Directory.CreateDirectory(directory);
            using (StreamWriter writeFile = new StreamWriter(path, true))
            {
                content = DateTime.Now + " : " + content;
                writeFile.WriteLine(content);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {
            writeLock.ExitWriteLock();
        }
    }
}

我有一个写日志的类。因为我正在异步写入日志,所以我需要在写入完成时放置一个锁并释放它,但这似乎是一个笨重的解决方案,甚至可能对性能有害。

有什么更好的方法可以解决这个问题?

2 个答案:

答案 0 :(得分:3)

出于性能原因以及为了避免log-ON和log-OFF之间出现非常不同的行为,我建议每个线程运行一个缓冲的日志文件。

  • 每个线程一个以避免锁定:无争用
  • 缓冲以避免磁盘延迟

对应方是:

  • 需要一个基于时间(毫秒)的合并工具来查看整个应用程序活动(vs线程活动)
  • 缓冲可能会在发生残酷终止时隐藏最后的日志记录

要进一步实时,您必须登录内存,并开发专用接口来提取登录请求,但这种日志通常保留给硬实时嵌入式应用程序。

低CPU消耗安全日志记录的其他解决方案(低级C编程):

  • 将日志记录缓冲区放入共享内存
  • 观察过程充当日志记录生成者
  • 创建一个具有更高优先级的日志管理器进程,该进程充当日志记录使用者
  • 管理翻转/翻牌机制背后的消费者和制作者之间的通信:关键部分下的指针分配。

如果观察到的进程崩溃,则由于共享内存段附加到日志管理器进程,因此不会丢失任何日志记录。

答案 1 :(得分:0)

在每个日志请求上打开,写入然后关闭文件都是多余且低效的。

在日志类上,使用缓冲区,并将该缓冲区的内容写入文件,每次X请求,关闭或每隔Y分钟。