2013-03-13 3 views
1

Log4Net이 a 파일에 로깅하는 DLL 파일이 있습니다. DLL을로드하고 DLL의 여러 인스턴스를 만들 수있는 프로세스가 있습니다.Log4Net은 리소스를 해제하지 않습니다.

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 은 애플릿을 종료하는 방법을 설명합니다. 하지만 문제는 내 소멸자에서 log.Logger.Repository.GetAppenders(); 빈 배열을 반환합니다.

어떻게 해결해야합니까?

그냥 내 DLL을로드하는 프로세스는 제 3 자의 프로세스이며 그 내부를 알지 못합니다.

+1

DLL의 인스턴스 란 무엇을 의미합니까? –

+0

죄송합니다. 자신을 잘못 표현하면 프로세스가 dll을로드 한 다음 dll에서 "주 클래스"의 인스턴스를 여러 인스턴스로 인스턴스화하므로 해당 클래스의 인스턴스마다 별도의 로그 파일이 있습니다. 클래스의 인스턴스가 파괴되면 내 파일은 여전히 ​​주 프로세스에 의해 잠긴 상태로 유지됩니다. – Tadzys

+0

"클래스의 인스턴스가 파괴되었습니다."도 심하게 표현되었습니다. .NET에서 객체 수명 및 가비지 수집에 대해 자세히 읽습니다. 그게 당신이이 과정과 왜 당신에게 문제를 일으키는 지 이해하는 데 도움이 될 것입니다. 참조 : http://stackoverflow.com/questions/12368/how-to-dispose-a-class-in-net/12394#12394 –

답변

4

사용자는 파일 (들) 소멸자가 호출됩니다 the language specification에서 1.6.7.6 소멸자에 따르면

를 해제 LogHelper의 소멸자를 사용하지만 당신은 때를 알 수 없다. 프로세스가 종료되기 전에 호출 될 것입니다.

할 수있는 가장 확실한 것은 명시 적으로 호출되는 방법 (예를 들어, Dispose)

당신이 파일을 메서드를 호출하여 해제 할 수 있습니다 그 방법에 소멸자의 논리를 이동하는 것입니다.

+0

아 ... 젠장, 아직도 내 C + +를 생각하고있다 .. 도와 줘서 고마워. – Tadzys

+1

문제 없습니다. 그것이 바로 우리가 여기있는 이유입니다. –

2

"소멸자"라고하는 것은 실제로는 Finalizer입니다. 관리되지 않는 리소스를 해제하는 데만 사용해야하므로 사용자가 악용하는 것처럼 보입니다. 또한 Finalizer는 별도의 스레드에서 호출 될 가능성이 높으며 효과적으로 임의의 시간에 호출 될 수 있으며 전혀 호출되지 않을 수도 있습니다.

LogHelperIDisposable을 구현하고 Dispose() (현재 Finalizer에있는 논리 포함)을 구현해야합니다.

그런 다음 적절한 시간에 Dispose()으로 전화하여 LogHelper의 수명을 관리해야합니다.

관련 문제