-2

I currently have a project that takes every x number of seconds (using Timer and a 10000 milliseconds Interval) the events happening on Windows and filters them under certain conditions. Each time the Timer does Tick, date and hour corresponding to 10 seconds before (due to the Interval) the moment events are checked, and the next method is executed:

// Method that returns wanted events from an EventLogEntryCollection
private List<EventLogEntry> lastEvents(EventLogEntryCollection eventsList, DateTime minimumMoment)
{
    // Wanted events list
    // 4624: Login
    // 4634: Logout
    long[] events = new long[] { 4624, 4634 };

    // Table to return with valid events
    List<EventLogEntry> filteredEventsList = new List<EventLogEntry>();

    // Checking if there are events to filter
    if (eventsList.Count > 0)
    {
        // There are events to filter
        // Going across all events to filter
        for (int i = 0; i < eventsList.Count; i++)
        {
            // Getting the current event
            EventLogEntry event = eventsList[i];   // Line with exception

            // Checking if the current event happened in the last 10 seconds (due to the Interval)
            if (event.TimeGenerated >= minimumMoment)
            {
                // The event is valid time wise
                // Checking if the event's ID is contained in the required ID's list
                if (events.Contains(event.InstanceId))
                {
                    // The event has a valid ID
                    // Adding the event to the list
                    filteredEventsList.Add(event);
                }
            }
        }
    }

    // Returning obtained list
    return filteredEventsList;
}

That event obtains a list of all events (obtained by using EventLog.Entries) and the date and time an event has to have to get added to the filtered events list (so an event had to be generated 10 seconds ago to be 'accepted'). But, during eventsList iterating, an IndexOutOfRangeException is generated being i on the first test around 28000 and on the second test 43, and the Count property around 31000 in both tests. ¿Is anyone able to tell me why this happens?

Here is a screenshot of the exception data (it is in Spanish, sorry): IndexOutOfRange exception data

mjwills
  • 23,389
  • 6
  • 40
  • 63

1 Answers1

0

As per the docs:

EventLogEntry objects are indexed by the event log system according to the chronological order in which they arrived in the event log. Use the Item[Int32] property to select a specific event log entry whose index in the collection is known.

Iterating through the EventLogEntryCollection instance steps through each EventLogEntry object sequentially. The collection is dynamic and the number of entries may not be immutable when you enter the loop. Therefore, you should use a for each...next loop instead of a for loop to step through entries that are associated with the EventLogEntryCollection instance to examine the entire set of entries.

Because new entries are appended to the existing list, stepping through the collection enables you to access the entries that were created after you originally created the EventLogEntryCollection.

Additionally, the docs for Count, state:

An EventLogEntryCollection represents a dynamic list of all the entries in a log. Therefore, the Count property can change during the lifetime of the EventLogEntryCollection instance that you create. It is usually best to work with the Count property directly instead of assigning its value to a variable.

So, in short, the Count is changing (likely reducing) - resulting in you looking up an index that no longer exists. Using foreach rather than for will solve this issue for you.

mjwills
  • 23,389
  • 6
  • 40
  • 63