1

Log4Net ロギングをファイルに記録する DLL ファイルがあります。DLL をロードし、DLL の複数のインスタンスを作成できるプロセスがあります。

DLL の各インスタンスは、個別のログ ファイルを作成する必要があります。したがって、私はすべての Log4Net 構成をプログラムで行います。

私はここからいくつかの助けを借りました。

これが私のコードです:

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 をロードするプロセスを停止しない限り、ログ ファイルが解放されることはなく、停止したくありません。

ここからのリンクで は、アペンダーをシャットダウンする方法が説明されています。しかし問題は、私のデストラクタで log.Logger.Repository.GetAppenders(); への呼び出しがあることです。空の配列を返します。

どのように解決すればよいですか?

注意: DLL をロードするプロセスはサードパーティのものであり、その内部構造はわかりません。

4

2 に答える 2

4

LogHelperのデストラクタを使用してファイルを解放しています

言語仕様の1.6.7.6デストラクタによると、デストラクタが呼び出されますが、いつかはわかりません。プロセスが終了する前に呼び出されることを知っているだけです。

最も明白なことは、デストラクタのロジックを明示的に呼び出されるメソッドに移動することです(例:Dispose

そうすれば、メソッドを呼び出してファイルを解放することができます。

于 2013-03-13T10:05:55.733 に答える
2

あなたが「デストラクタ」と呼ぶものは実際にはFinalizerです。管理されていないリソースを解放するためにのみ使用する必要があるため、悪用しているように見えます。また、ファイナライザーは別のスレッドで呼び出される可能性が高く、事実上ランダムな時間に呼び出される可能性があり、まったく呼び出されない可能性があることにも注意してください。

LogHelper実装IDisposableと実装を行う必要がありますDispose()(これには、現在ファイナライザーにあるロジックが含まれます)。

次に、適切な時間LogHelperに電話をかけて、あなたの生涯を管理する必要があります。Dispose()

于 2013-03-13T10:06:09.287 に答える