2009-12-22 2 views
2

나는액세스

ThreadPool.QueueUserWorkItem(o => service.Method(arg1, arg2));

서비스를 사용하여 서비스 메소드를 호출 객체 loggingService '나는 Spring.Net

을 사용하여 얻을되었다에

private readonly ILoggingService loggingService = ObjectBuilder.GetObjectByName("LoggingService");

'LoggingService '이있다 클래스는 싱글 톤입니다. 로그 정보를 log.txt에 기록합니다.

이 서비스 메서드에서 loggingService.Info ("test")를 호출하려고하면 예외가 발생합니다. 파일이 다른 프로세스에서 사용 중입니다.

loggingService에 액세스하려면 어떻게해야합니까?

+0

어떤 프로그래밍 언어 당신에 대해 물어

나는 대기열 및 스레딩 사용합니까? –

+0

오. 죄송합니다. 나는 C# (WPF Application)을 사용한다. – Justinetz

+0

그는 C# 3을 사용한다. – SLaks

답변

1

당신의 싱글 톤은 분명히 스레드 당입니다.
스레드를 가로 질러 LoggingService을 넘기는 방법이 필요합니다.

예를 들어 원래 스레드에 service.loggingService을 설정할 수 있습니다.

또는 Spring.Net을 비 스레드 로컬 싱글 톤으로 구성 할 수 있습니다.

LoggingService는 스레드로부터 안전해야하며 그렇지 않으면 런타임에 이상한 오류가 발생합니다.

0

많은 스레드를 사용하는 클라이언트 측 응용 프로그램을 작성하는 동안 비슷한 문제가있었습니다.

기본적으로 LoggingService는 내부 대기열 (액세스를 잠금을 통해 제어해야 함)을 유지하기를 원하며 로그 메소드를 호출 할 때마다 메시지를이 대기열에만 추가합니다. 로그 메소드가 끝나면 큐가 현재 파일에 쓰여져 있는지 확인하고, 그렇지 않으면 쓰기를 시작하십시오.

0
public static class SingletonLoggingService 
{ 
    public static ILoggingService LoggingService = ObjectBuilder.GetObjectByName("LoggingService"); 
} 


SingletonLoggingService.LoggingService.Info("Test"); 
0

나는 그것을했다!

internal class LoggingService : ILoggingService { 
    private readonly Queue<LogEntry> queue = new Queue<LogEntry>(); 
    private Thread waiter; 

    public LoggingService() { 
     waiter = new Thread(AddLogEntry); 
     waiter.Start(); 
    } 

    public void Shutdown() { 
     try { 
      waiter.Abort(); 
     } catch {} 
    } 

    public void Error(string s, Exception e) { 
     lock (queue) { 
      queue.Enqueue(new LogEntry(s, e, LogEntryType.Error)); 
     } 
    } 

    public void Warning(string message) { 
     lock (queue) { 
      queue.Enqueue(new LogEntry(message, LogEntryType.Warning)); 
     } 
    } 

    public void Info(string message) { 
     lock (queue) { 
      queue.Enqueue(new LogEntry(message, LogEntryType.Info)); 
     } 
    } 

    private void AddLogEntry(object state) { 
     while (true) { 
      lock (queue) { 
       if (queue.Count > 0) { 
        LogEntry logEntry = queue.Dequeue(); 
        switch (logEntry.Type) 
        { 
         case LogEntryType.Error: 
          logWriter.Error(logEntry.Message, logEntry.Exception); 
          break; 
         case LogEntryType.Warning: 
          logWriter.Warning(logEntry.Message); 
          break; 
         case LogEntryType.Info: 
          logWriter.Info(logEntry.Message); 
          break; 
        } 
       } 
      } 
      Thread.Sleep(100); 
      if (waiter.ThreadState == ThreadState.Aborted) { 
       waiter = null; 
       break; 
      } 
     } 
    } 
} 

내가 전화 종료() 응용 프로그램의 끝에 :

 protected override void OnExit(ExitEventArgs e) { 
     loggingService.Shutdown(); 
     base.OnExit(e); 
    }