Поделиться через


Журналы событий и многопоточные компоненты

Журналы событий предназначены для отслеживания важных событий во время выполнения приложения. В журналы событий записываются данные, которые могут пригодиться при устранении неполадок или анализе производительности. При записи событий для многопоточных компонентов необходимо учитывать дополнительные особенности. Во-первых, должен быть предусмотрен механизм для записи идентификационных данных потока, в котором регистрируется сообщение. Во-вторых, при взаимодействии с журналом событий должны быть приняты во внимание вопросы потокобезопасности. Во избежание состояния гонки поток, пытающийся записать сообщение, должен установить монопольную блокировку для журнала. Обзор журналов событий см. в разделе Администрирование журналов событий. Дополнительные сведения о потокобезопасности см. в разделе Потокобезопасные компоненты.

Чтобы идентифицировать каждый поток, необходимо задать значение свойства Thread.Name. Это свойство принимает и возвращает значение типа String и может быть использовано для назначения уникального идентификатора каждому потоку. Затем это значение можно передать в метод EventLog.CreateEventSource, чтобы определить данный поток в качестве источника событий для других потоков. При записи событий в журнал поток может задать свое имя в качестве значения свойства Source журнала событий, обеспечивая таким образом точность записи событий.

Если несколько строк кода выполняются в многопоточной среде, важно, чтобы перед выполнением любого кода потоки устанавливали монопольные блокировки для журнала событий. Рассмотрим, например, следующие строки кода, выполняющиеся в многопоточной среде:

MyEventLog.Source = Threading.Thread.CurrentThread.Name.ToString
EventLog.WriteEntry("What thread did this come from?", "myApplication")
MyEventLog.Source = System.Threading.Thread.CurrentThread.Name.ToString();
EventLog.WriteEntry("What thread did this come from?", "myApplication");

Если несколько потоков выполняют эти строки кода одновременно, то в одном потоке может быть изменено свойство EventLog.Source журнала событий, а в другом потоке — записано сообщение уже после изменения значения этого свойства. Чтобы избежать подобных ситуаций, можно перед выполнением кода из нескольких потоков установить монопольную блокировку объекта с помощью оператора SyncLock (Visual Basic) или lock (C#). С использованием блокировок предыдущий пример будет выглядеть следующим образом:

SyncLock MyEventLog
   MyEventLog.Source = System.Threading.Thread.CurrentThread.Name.ToString
   EventLog.WriteEntry("What thread did this come from?", "myApplication")
End SyncLock
lock(MyEventLog)
{
   MyEventLog.Source = Threading.Thread.CurrentThread.Name.ToString();
   EventLog.WriteEntry("What thread did this come from?", 
      "myApplication");
}

Для записи событий, которые происходят в многопоточных приложениях, можно также использовать классы Debug и Trace. Эти классы являются статическими и позволяют отправлять выходные данные в окно вывода, окно консоли, текстовый файл, журнал событий или другие объекты. Дополнительные сведения см. в разделе Трассировка и оборудование приложений в Visual Basic и Visual C#.

См. также

Задачи

Практическое руководство. Ведение журнала событий для многопоточных компонентов

Другие ресурсы

Многопоточность в компонентах