2009-11-09 2 views
2

У меня есть что-то, похожее на меня, как состояние гонки, при входе в файл от несколько потоков.Состояние гонки/TextWriterTraceListener

1) У меня есть пользовательский класс logger (ConfigurableTraceLogger), который используется несколькими потоками в моем приложении. Это имеет множество функций-оболочек, которые все вызов главной основной функции

protected void TraceData(String category, TraceEventType type, EventId id, string prefix, string format) 
{ 
    foreach (TraceListener item in _listeners) 
    { 
     IConfigurableTraceListener cl = item as IConfigurableTraceListener; 

     if (cl != null && cl.Category == category.ToLower()) 
     { 

      if (DisplayMethodName) 
       item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format); 
      else 
       item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, format); 

      item.Flush(); 
     } 
    } 
} 

Как вы можете видеть мой класс просто хранит различную TraceListner-derved класс в коллекции _listeners. В основном есть только консольные и текстовые файлы. То, что TraceData делает, требует название категории (то есть запуск журнала) и находит правильный прослушиватель. Все слушатели определяются по имени файла конфигурации

Теперь у меня есть свои собственные слушателей в коллекции

public class ConfigurableTextWriterTraceListener : TextWriterTraceListener, IConfigurableTraceListener 

Это пользовательский класс не переопределяет ничего для одного свойства, за исключением.

protected override string[] GetSupportedAttributes() 
{ 
    return new string[] { "category" }; 
} 

Когда я начинаю свое заявление после того, как 5 до 10 минут я получаю исключение на вызов

  item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format); 

Exception говорит:

«Вероятная I/O состояние гонки обнаружена при копировании Пакет I/O по умолчанию не является потокобезопасным. В многопоточных приложениях поток должен быть доступен поточно-безопасным способом, таким как потокобезопасная оболочка, возвращаемая методами Synchronized TextReader или TextWriter. применяется к таким классам, как StreamWriter и StreamReader ».

После этого я получаю второе исключение много раз на тот же призыв к

item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format); 

Exception

Count не может быть меньше нуля. Имя параметра: count Трассировка стека: «at System.String.CopyTo (Int32 sourceIndex, Char [] destination, Int32 destinationIndex, Int32 count) \ r \ n в System.IO.StreamWriter.Write (String value) \ r \ n в System.Diagnostics.TextWriterTraceListener.Write (сообщение String) \ r \ n в System.Diagnostics.TraceListener.WriteHeader (источник String, TraceEventType eventType, Int32 id) \ r \ n в System.Diagnostics.TraceListener.TraceData (TraceEventCache eventCache , String source, TraceEventType eventType, Int32 id, Данные объекта) \ r \ n в Jfc.Configuration.ConfigurableTraceLogger.TraceData (категория строк, тип TraceEventType, идентификатор события, префикс строки, строковый формат, объект [] args) "

Мне кажется, что мой класс не является потокобезопасным, а также вызовом TraceData. Но ConfigurableTextWriterTraceListener называется потокобезопасным в конце концов. Тем не менее я проверил IsThreadSafe propety для моего производного класса TextWriterTraceListener во время выполнения , и он ошибочен. Я пытаюсь выяснить, где проблема.

+0

Пожалуйста, помечать с язык, который вы используете –

+0

Я не вижу кнопку «Изменить» здесь. Где это? Или вы имеете в виду следующие должности? –

ответ

1

Это означает, что говорит - ваш TraceListener не является потокобезопасным и ломается при доступе из нескольких потоков. Вам нужно сделать потоки прослушивателей потоками или найти способ обеспечить, чтобы только один поток обращался к любому конкретному экземпляру.

Один из способов сделать их потокобезопасными - использовать синхронизированную очередь и сделать все ваши вызовы в очереди элементов данных в очередь, в то время как «real» traceListener удаляет их из очереди и записывает их в отдельный поток.

Вы также должны быть осторожны с вашим словарем слушателей - обновление словаря не Потокобезопасная, но если вы никогда не получить доступ к нему перед нанесением последнего обновления, вы можете оставить его как

+0

Ну спасибо! Согласен, что я должен создать безопасный журнал регистрации на основе очереди. Но все же у меня нет ответа - почему состояние гонки - в методе TraceData, полученном TextWriterTraceListner, когда MSDN говорит, что этот класс является потокобезопасным? Я полагаю, это означает, что многие потоки могут безопасно вызывать эти методы. Но, похоже, они не могут. PS Я не трогаю словарь, который он построил .NET из файла конфигурации, и регистрация начинается гораздо позже. –

+0

'Все публичные статические (Shared in Visual Basic) члены этого типа являются потокобезопасными. Любые члены экземпляра не гарантируются потокобезопасностью. Это берется непосредственно из справки класса TextWriterTraceListener. – mfeingold

+0

Вправо - поэтому он ни в коем случае не статичен. Благодарю. –

Смежные вопросы