Состояние гонки / TextWriterTraceListener - PullRequest
2 голосов
/ 09 ноября 2009

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

1) У меня есть собственный класс регистратора (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 в коллекции _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);

Исключение говорит:

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

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

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

Исключение

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

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

1 Ответ

1 голос
/ 09 ноября 2009

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

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

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

...