【问题标题】:C# correct implementation of a StreamWriter for a logger class记录器类的 StreamWriter 的 C# 正确实现
【发布时间】:2020-05-17 19:53:43
【问题描述】:

我的项目遇到了一个奇怪的问题。

这是我的记录器类:

using System.Diagnostics;
using System.IO;

namespace someSpace
{
    public enum LogTarget
    {
        File, Database, EventLog
    }

    public static class LogHelper
    {
        private static LogBase logger = null;
        public static void Log(LogTarget target, string path, string message)
        {
            switch (target)
            {
                case LogTarget.File:
                    logger = new FileLogger();
                    logger.Log(path, message);
                    break;
                case LogTarget.EventLog:
                    logger = new EventLogger();
                    logger.Log("", message);
                    break;
                default:
                    return;
            }
        }
    }

    public abstract class LogBase
    {
        protected readonly object lockObj = new object();
        public abstract void Log(string path, string message);
    }

    public class FileLogger : LogBase
    {
        public override void Log(string path, string message)
        {
            lock (lockObj)
            {
                File.Open(path, FileMode.Open).Close();
                using (StreamWriter streamWriter = new StreamWriter(path))
                {
                    streamWriter.WriteLine(message);
                    streamWriter.Close();
                }
            }
        }
    }

    public class EventLogger : LogBase
    {
        public override void Log(string path, string message)
        {
            lock (lockObj)
            {
                EventLog m_EventLog = new EventLog("");
                m_EventLog.Source = "IDGEventLog";
                m_EventLog.WriteEntry(message);
            }
        }
    } 
} 

我这样调用函数Log...

LogHelper.Log(LogTarget.File, LOG_FILE_PATH, e.ToString());

我假设通过在我的类中使用构造“使用”,流将自动关闭,随后文件将被关闭并释放。

这不会发生;程序的后续运行一直说该文件仍在被某个进程使用。我不知道如何诊断问题。

lock (lockObj)
{
    var file = File.Open(path, FileMode.Open);

    using (StreamWriter streamWriter = new StreamWriter(file))
    {
        streamWriter.WriteLine(message);
        streamWriter.Close();
    }

    file.Close();
}

也修改了这种方式作为评论提示,但问题仍然存在......

【问题讨论】:

  • 我认为你应该做 var file = File.Open.. ,然后是你的 using,然后是 file.Close();。否则,您似乎一打开它就关闭它
  • 当 .NET 有许多功能齐全、强大且高性能的选项时,您是否有理由滚动自己的记录器?正如您已经发现的那样,日志记录并非易事。
  • 是的,File.Open(path, FileMode.Open).Close(); 很奇怪,尤其是当您立即使用 StreamWriter 重新打开同一个文件时。另外,你locklockObj,大概是为了防止对同一个LogBase的多次调用互相践踏。但是随后您为 每个 Log() 调用创建了一个新的LogBase,并使用它自己的lockObj,所以这不会保护任何东西。此外,如果两个Log() 调用同时发生在同一个LogTarget不同 paths,这是(试图)让一个等待另一个,这是不必要的.
  • @Crowcoder 这个项目主要是对一个用 Java 编写的旧的类似应用程序的改进,对我来说更像是一个练习,因为我更喜欢自动化我通常编写 PLC 代码,我需要保持我的思想训练有素,所以我想自己写...问题是我的记录器不应该很复杂,它只需要向文件中添加一些字符串就可以了... :(

标签: c# logging


【解决方案1】:

每次调用 Log 都会创建一个带有自己 lockObj 的新 logger,其他 logger 不会被锁定。使 lockObj 成为静态成员。

【讨论】:

  • 使 lockObj 成为静态似乎已经解决了它:) 谢谢!如果你不介意你能解释一下为什么吗?对不起,这可能是一个非常愚蠢的问题......
  • 一个静态成员作为一个单例,所以最多一个记录器可以使用它。
  • 好的,非常感谢您的解释似乎很简单:) 现在可以正常工作了!现在还有一些 bug 可以解决 XD
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-30
  • 2012-07-13
  • 2018-07-20
  • 2016-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多