我有一个DLL文件,它将Log4Net记录到一个文件中。有一个加载DLL的进程可以创建DLL的多个实例。
DLL的每个实例都必须创建一个单独的日志文件。因此,我以编程方式执行所有Log4Net配置。
我使用了here.
的一些帮助这是我的代码:
public class LogHelper
{
private PatternLayout _layout = new PatternLayout();
private const string LOG_PATTERN = "%date %-5level - %message%newline";
private String Configuration;
public static string DefaultPattern
{
get { return LOG_PATTERN; }
}
public ILog log = null;
public LogHelper(String configuration)
{
Configuration = configuration;
InitialiseLogger();
_layout.ConversionPattern = DefaultPattern;
_layout.ActivateOptions();
Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
hierarchy.Configured = true;
hierarchy.LevelMap.Add(log4net.Core.Level.Debug);
hierarchy.LevelMap.Add(log4net.Core.Level.Critical);
hierarchy.LevelMap.Add(log4net.Core.Level.Info);
hierarchy.LevelMap.Add(log4net.Core.Level.Warn);
hierarchy.LevelMap.Add(log4net.Core.Level.Error);
hierarchy.LevelMap.Add(log4net.Core.Level.Fatal);
}
~LogHelper()
{
log.Debug("Closing myself down");
IAppender[] appenders = log.Logger.Repository.GetAppenders();
//appenders are empty
log.Logger.Repository.Shutdown();
}
public void InitialiseLogger()
{
Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
Logger newLogger = hierarchy.GetLogger(Configuration) as Logger;
PatternLayout patternLayout = new PatternLayout();
patternLayout.ConversionPattern = LOG_PATTERN;
patternLayout.ActivateOptions();
RollingFileAppender roller = new RollingFileAppender();
roller.Layout = patternLayout;
roller.AppendToFile = true;
roller.RollingStyle = RollingFileAppender.RollingMode.Size;
roller.MaxSizeRollBackups = 4;
roller.MaximumFileSize = "10MB";
String name = String.Format("-{0:yyyy-MM-dd_HH-mm-ss}", DateTime.Now);
roller.File = "C:\\Logs\\" + Configuration + name + ".log";
roller.ImmediateFlush = true;
roller.ActivateOptions();
newLogger.AddAppender(roller);
log = LogManager.GetLogger(Configuration);
}
问题是log.Debug(“关闭自己”);未记录到日志文件中;我知道它被称为。并且日志文件永远不会被释放,除非我停止加载我的DLL0的进程,并且我不想阻止它。
来自here的链接 解释了如何关闭appender。但问题是在我的析构函数中调用log.Logger.Repository.GetAppenders();返回一个空数组。
我该如何解决?
请注意:加载我的DLL的过程来自第三方,我不知道它的内部。
答案 0 :(得分:4)
您正在使用LogHelper的析构函数来释放文件
根据the language specification中的1.6.7.6析构函数,析构函数将被调用,但您无法知道何时。您只知道在进程终止之前将调用它。
最明显的做法是将析构函数的逻辑移动到一个将被显式调用的方法(例如Dispose)
这样你就可以调用该方法,从而释放文件。
答案 1 :(得分:2)
你称之为“析构函数”实际上是Finalizer
。它们应该只用于释放非托管资源,所以它看起来像你在滥用它。另请注意,Finalizer可能会在一个单独的线程上调用,它可能会在一个随机的时间内被调用,甚至可能根本不被调用。
您应该LogHelper
实施IDisposable
并实施Dispose()
(其中包含当前在Finalizer中的逻辑)。
然后,您需要在适当的时候致电LogHelper
来管理Dispose()
的生命周期。