Event Logs and Multithreaded Components

Event logs are for keeping track of significant events when an application is running. Using event logs, you can record information that might be useful for troubleshooting or performance analysis. There are additional considerations when logging events with multithreaded components. First, there must be a mechanism to record the identity of the thread logging the message. Second, thread safety must be taken into account when interacting with the event log. The thread attempting to write a message must obtain an exclusive lock on the log in order to avoid race conditions. For an overview of event logs, see Administering Event Logs. For more information on thread safety, see Thread-Safe Components.

To identify each thread, you should set the Thread.Name Property. This property takes and returns a String value, and can be used to set a unique identifier for each thread. This value can then be passed to the EventLog.CreateEventSource Method to designate your thread as an event source for each thread. When logging events, your thread can set the Source property of the event log to its name, thereby ensuring accurate logging of events.

When executing multiple lines of code in a multithreaded environment, it is important that the threads obtain exclusive locks on the event log before executing any code. For example, consider the following lines of code, executed in a multithreaded environment:

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");

If multiple threads are executing these lines simultaneously, if is possible for one thread to change the EventLog.Source Property of the event log, and for another thread to write a message, after that property had been changed. In order to avoid conditions such as these, you can use the SyncLock Statement (Visual Basic) or lock (C#) statement to obtain an exclusive lock on the object before executing code from multiple threads. Using locking, the previous example would now look like the following:

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

You can also use the Debug and Trace classes to log events that occur in multithreaded applications. These classes are static classes that allow you to send output to the output window, the console window, a text file or event log, or any other of a number of objects. For details, see Tracing and Instrumenting Applications in Visual Basic and Visual C#.

See Also

Tasks

How to: Log Events for Multithreaded Components

Other Resources

Multithreading in Components