Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens if a new Entry is written to the Event Log while the application is inside the handler for a previous entry being written?

My application needs to review all new application Event Log entries as they come in.

private void eventLog_Application_EntryWritten(object sender, EntryWrittenEventArgs e)
{
    // Process e.Entry    
}

What I would like to know is what happens if another Entry is written to the EventLog while a previous Entry is being handled?


The documentation for EventLog.EntryWritten Event provides an example of handling an entry written event which uses threading (which is why I am asking the question).

In this example they use System.Threading and call the WaitOne() and Set() methods on the AutoResetEvent class, however I'm not sure precisely what this code is intended to achieve.

The documentation states that - WaitOne() "blocks the current thread until the current WaitHandle receives a signal", and that Set() "sets the state of the event to signaled, allowing one or more waiting threads to proceed". I'm not sure what the threading portion of this example is intended to demonstrate, and how this relates to how (or if) it needs to be applied in practice.

It appears that WaitOne() blocks the thread immediately after the entry has been written, until it has been handled, where it is then set to signalled (using Set()), before allowing the thread to proceed. Is this the one and only thread for the application?

Most importantly, when my application is not responsible for writing the the events which need to be read from the EventLog, how should this principle be applied? (If, indeed, it needs to be applied.)

What does happen if a new Entry is written while the application is inside the handler?

like image 660
Eilidh Avatar asked Apr 16 '15 13:04

Eilidh


People also ask

How will you save the events shown in the event log for future reference?

To save event logs right-click the appropriate log file (Application, Security, System, Directory Service, or File Replication Service) then click Save All Events As. Type a name for the file, and click Save.

How do I log an application for an event?

Open "Event Viewer" by clicking the "Start" button. Click "Control Panel" > "System and Security" > "Administrative Tools", and then double-click "Event Viewer" Click to expand "Windows Logs" in the left pane, and then select "Application". Click the "Action" menu and select "Save All Events As".

What is the Windows application event log?

Windows event log is an in-depth record of events related to the system, security, and application stored on a Windows operating system. Event logs can be used to track system and some application issues and forecast future problems.

How do you write an event log?

The Write-EventLog cmdlet writes an event to an event log. To write an event to an event log, the event log must exist on the computer and the source must be registered for the event log. The cmdlets that contain the EventLog noun (the EventLog cmdlets) work only on classic event logs.


2 Answers

Nothing dramatic happens, it is serialized by the framework. The underlying winapi function that triggers the EventWritten event is NotifyChangeEventLog(). The .NET Framework uses the threadpool to watch for the event to get signaled with ThreadPool.RegisterWaitForSingleObject(). You can see it being used here.

Which is your cue to why the MSDN sample uses ARE (AutoResetEvent). The event handler runs on that threadpool thread, exactly when that happens is unpredictable. The sample uses a console mode app, without that ARE it would immediately terminate. With the ARE, it displays one notification and quits. Not actually that useful of course, I would personally just have used Console.ReadLine() in the sample so it just keeps running and continues to display info until you press the Enter key.

You don't need this if you use a service or a GUI app, something that's going to run for a long time until the user explicitly closes it. Note the EventLog.SynchronizingObject property, makes it easy to not have to deal with the threadpool thread in a Winforms app.

like image 151
Hans Passant Avatar answered Oct 26 '22 23:10

Hans Passant


The example is not really helping to explain the way the AutoResetEvent works in a multi-threaded scenario, so I'll try to explain how I understand it to work.

The AutoResetEvent signal static variable, is instantiated as a new AutoResetEvent with its signaled state set to false, or "non-signaled", meaning that calling signal.WaitOne() will cause the thread that called WaitOne to wait at that point, until the signal variable is "set" by calling the signal.Set() method.

I found an explanation of AutoResetEvent that describes it very well in understandable real-world terms, which also included this excellent example below. http://www.albahari.com/threading/part2.aspx#_AutoResetEvent

AutoResetEvent

An AutoResetEvent is like a ticket turnstile: inserting a ticket lets exactly one person through. The “auto” in the class’s name refers to the fact that an open turnstile automatically closes or “resets” after someone steps through. A thread waits, or blocks, at the turnstile by calling WaitOne (wait at this “one” turnstile until it opens), and a ticket is inserted by calling the Set method. If a number of threads call WaitOne, a queue builds up behind the turnstile. (As with locks, the fairness of the queue can sometimes be violated due to nuances in the operating system). A ticket can come from any thread; in other words, any (unblocked) thread with access to the AutoResetEvent object can call Set on it to release one blocked thread.

class BasicWaitHandle
{
  static EventWaitHandle _waitHandle = new AutoResetEvent (false);

  static void Main()
  {
    new Thread (Waiter).Start();
    Thread.Sleep (1000);                  // Pause for a second...
    _waitHandle.Set();                    // Wake up the Waiter.
  }

  static void Waiter()
  {
    Console.WriteLine ("Waiting...");
    _waitHandle.WaitOne();                // Wait for notification
    Console.WriteLine ("Notified");
  }
}
like image 27
Zack Avatar answered Oct 27 '22 00:10

Zack