У меня есть что-то похожее на состояние гонки при входе в файл с
многопоточность.
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 во время выполнения
и это ложь. Я пытаюсь выяснить, где проблема.