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

标签 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();
        }
    }
}

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

有什么更好的方法来处理这个问题?

最佳答案

出于性能原因,也为了避免登录和注销之间出现截然不同的行为,我建议每个线程运行一个缓冲日志文件。

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

对应的部分是:

  • 需要基于时间(毫秒)的合并工具来查看整个应用程序事件(与线程事件)
  • 缓冲可能会隐藏最后的日志记录,以防粗暴终止

要想更接近实时,就必须将日志记录在内存中,并开发专门的接口(interface)来根据请求提取日志,但这种日志通常保留给硬实时嵌入式应用。

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

  • 将日志记录缓冲区放入共享内存
  • 被观察的进程充当日志记录生产者
  • 创建一个具有更高优先级的日志管理进程,充当日志记录消费者
  • 通过触发器机制管理消费者和生产者之间的通信:临界区下的指针分配。

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

关于c# - 处理异步日志写入的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13024433/

相关文章:

c# 语法快捷方式在连续多次引用对象名称时跳过它

c# - 为什么进入静态 .ctors 的顺序与继承类中的实例 .ctors 不同?

c# - WPF:删除标题/控制框

c# - 不知道如何创建 SOAP <wsse :Security> header

c++ - 写入时 WaitForMultipleObjects 访问冲突

python - 发生异常时停止线程

c# - 启动多个线程,为什么必须等待?

c# - 如何以编程方式控制从 T4 生成的新文件的构建操作?

.net - 新手 .net 问题 - 相当于 $_SESSION ['SERVER_NAME' 的变量]

java - Scala 和 Java 的 future 显然有意想不到的互动