自定义记录器类的性能,对于读取Word文档的应用程序而言

问题描述 投票:1回答:1

我有一个应用程序,它使用OpenXmlPowerTools从.docx文件中读取注释和段落。它是一个控制台应用程序,运行时会创建一个debug.log文件。

实现了一个记录器类,该类将所有版本的消息保存到文本文件,并将这些消息打印到控制台以进行调试版本。以下代码是该记录器类的一部分:

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秒才能完成。无需登录,只花了几秒钟。经过一些调查,.NET中File.AppendText的运行速度似乎很慢。

作为替代,我尝试使用缓冲区:

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

与我在推荐该方法的文章中看到的信息相反,性能似乎有所下降(耗时超过2分钟)。为什么是这样?我如何改善其性能?

c# .net file logging streamwriter
1个回答
0
投票

您的记录代码是错误的。这是15年前企业图书馆的开始方式,但结果并不理想。使用日志记录框架并完成它。

现在是您的实际问题。您为每次日志调用打开和关闭文件,这非常慢,并且会导致大量开销。保持日志文件和StreamWriter处于打开状态,并使用锁确保不会同时将数据写入日志文件。接下来,您需要处理生命周期问题,因为如果首先完成FileStream,您的StreamWriter将无法将待处理的数据刷新到磁盘,并且您将释放最后的日志消息(很可能是发生崩溃异常消息的重要消息)。

要解决每个日志上的刷新问题,请调用StreamWriter(缓慢)或创建一个包装类,该包装类从CriticalFinalizerObject派生并保持FileStream打开,并在FileStream实例上调用GC.SuppressFinalize,以防止在应用程序关闭时尽早完成操作。

这是在创建自己的日志记录库时遇到的最常见的陷阱。

© www.soinside.com 2019 - 2024. All rights reserved.