2009-12-22 3 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

Что программирования вы спрашиваете о? – 2009-12-22 14:23:09

+0

Ох. Сожалею. Я использую C# (приложение WPF) – 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

Я сделал это!

Я использую Queue и нарезание резьбы:

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; 
      } 
     } 
    } 
} 

Я называю Shutdown() в конце приложения:

языка
 protected override void OnExit(ExitEventArgs e) { 
     loggingService.Shutdown(); 
     base.OnExit(e); 
    } 
Смежные вопросы