.net 自定义日志记录器类的性能分析,用于阅读Word文档的应用程序

zdwk9cvp  于 2023-10-21  发布在  .NET
关注(0)|答案(1)|浏览(95)

我有一个应用程序,它使用OpenXmlPowerTools从.docx文件中读取注解和段落。它是一个控制台应用程序,在运行时创建一个debug.log文件。
实现了一个logger类,它在所有构建中将消息保存到文本文件中,并将这些消息打印到控制台以进行调试构建。下面的代码是这个logger类的一部分:

public static class Logger
{
    public enum LogLevel
    {
        ERROR, WARNING, DEBUG
    }

    public static void Log(string message, LogLevel level, bool newline)
    {
        try
        {
            // the very next line was a hotspot, as shown in the profiler
            using (StreamWriter sw = File.AppendText(path))
            {
                // write the messages to this file
            }
        }
        catch (Exception ex)
        {
            // handle it
            // I know it is bad practice to catch System.Exception, I need to fix this.
        }
     }
}

在代码中,这个函数经常被这样调用:

private void doSomething(string someParameter)
{
    Logger.Log("The parameter is: " + someParameter, Logger.LogLevel.DEBUG, true);
}

我已经分析了它的性能,对于一个相当大的有几十条评论的word文档,它花了1分40秒才完成。如果没有日志记录,只需要几秒钟。经过一些调查,似乎File.AppendText在. NET中非常慢。
作为替代,我尝试使用缓冲区:

using (StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8, 65536)
{
    // write the messages to the file
}

与我读过的一篇推荐这种方法的文章中的信息相反,性能似乎恶化了(花费超过2分钟)。为什么会这样呢?我如何提高它的性能?

9fkzdhlc

9fkzdhlc1#

您的登录代码错误。这就是企业图书馆15年前开始的方式,结果并不好。使用一个日志框架并完成它。
现在谈谈你的实际问题。每次日志调用都要打开和关闭文件,速度非常慢,会造成很大的开销。保持日志文件和StreamWriter打开,并使用锁来确保不会并发地将数据写入日志文件。接下来,你需要处理生存期问题,因为如果FileStream首先完成,你的StreamWriter将无法将挂起的数据刷新到磁盘,并且你会丢失最后的日志消息(最有可能是崩溃异常消息的重要消息)。
要解决每个日志上的刷新,请调用StreamWriter(慢)或创建一个从CriticalFinalizerObject派生的 Package 器类,并保持FileStream打开,并在FileStream示例上调用GC.SuppressFinalize以防止应用程序关闭期间提前终止。
这是在创建自己的日志库时最常见的陷阱。
例如,一个小型的日志记录器。这里(我写的):https://github.com/Alois-xx/WMIWatcher/blob/master/FileLogger.cs

相关问题