Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为读取Word文档的应用程序提供自定义记录器类的性能_C#_.net_File_Logging_Streamwriter - Fatal编程技术网

C# 为读取Word文档的应用程序提供自定义记录器类的性能

C# 为读取Word文档的应用程序提供自定义记录器类的性能,c#,.net,file,logging,streamwriter,C#,.net,File,Logging,Streamwriter,我有一个应用程序,它使用OpenXmlPowerTools从.docx文件中读取注释和段落。它是一个控制台应用程序,在运行时创建debug.log文件 实现了一个logger类,它将消息保存到所有版本中的文本文件中,并将这些消息打印到控制台以进行调试版本。以下代码是此记录器类的一部分: public static class Logger { public enum LogLevel { ERROR, WARNING, DEBUG } publi

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

实现了一个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分钟以上)。为什么会这样?如何提高此功能的性能?

您的日志代码错误。这就是Entprise Library在15年前的起步方式,但结果并不理想。 使用日志框架并完成它

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

要解决每次日志刷新的问题,请调用StreamWriter(慢速)或创建一个包装类,该类派生自CriticalFinalizerObject并保持FileStream打开,然后在FileStream实例上调用GC.SuppressFinalize以防止在应用程序关闭期间提前完成

这是创建自己的日志库时最常见的陷阱

一个小型记录器,例如:

您的意思是使用块将整个代码包装在
中吗?我不熟悉锁。您能提供一些示例代码来说明您的意思吗,或者给我指出一些我可以阅读的资源来帮助解决这个问题吗?我添加了一个小的记录器示例,它完成了大部分工作。