【发布时间】: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 代码,我需要保持我的思想训练有素,所以我想自己写...问题是我的记录器不应该很复杂,它只需要向文件中添加一些字符串就可以了... :(