Severity: Warning
File: src/Servy.Core/Logging/EventLogReader.cs
Lines: 15-33
Code:
public IEnumerable<ServyEventLogEntry> ReadEvents(EventLogQuery query)
{
using (var reader = new System.Diagnostics.Eventing.Reader.EventLogReader(query))
{
var results = new List<ServyEventLogEntry>();
for (EventRecord evt = reader.ReadEvent(); evt != null; evt = reader.ReadEvent())
{
using (evt) { results.Add(MapToDto(evt)); }
}
return results;
}
}
Explanation:
ReadEvents reads every record matching the EventLogQuery into an in-memory List<ServyEventLogEntry> before returning. The caller (EventLogService.SearchAsync) then applies MaxResults = 10_000 after the fact, by breaking out of its own iteration:
results.Add(evt);
if (results.Count >= MaxResults) break;
But that break only short-circuits the SECOND filter loop — ReadEvents has already pulled and materialized the entire underlying result set. On a busy host (Application log can hold tens or hundreds of thousands of entries that match a broad query), this can balloon memory and freeze the UI thread that triggered the query, even though the visible result is capped at 10,000.
Suggested fix:
Make ReadEvents a true streaming enumerator (yield return), so the caller-side break actually stops the SCM-side cursor:
public IEnumerable<ServyEventLogEntry> ReadEvents(EventLogQuery query)
{
using (var reader = new System.Diagnostics.Eventing.Reader.EventLogReader(query))
{
for (EventRecord evt = reader.ReadEvent(); evt != null; evt = reader.ReadEvent())
{
using (evt) { yield return MapToDto(evt); }
}
}
}
Alternatively, pass MaxResults into ReadEvents and stop reading once that many records have been mapped.
Severity: Warning
File:
src/Servy.Core/Logging/EventLogReader.csLines: 15-33
Code:
Explanation:
ReadEventsreads every record matching the EventLogQuery into an in-memoryList<ServyEventLogEntry>before returning. The caller (EventLogService.SearchAsync) then appliesMaxResults = 10_000after the fact, by breaking out of its own iteration:But that break only short-circuits the SECOND filter loop —
ReadEventshas already pulled and materialized the entire underlying result set. On a busy host (Application log can hold tens or hundreds of thousands of entries that match a broad query), this can balloon memory and freeze the UI thread that triggered the query, even though the visible result is capped at 10,000.Suggested fix:
Make
ReadEventsa true streaming enumerator (yield return), so the caller-sidebreakactually stops the SCM-side cursor:Alternatively, pass
MaxResultsintoReadEventsand stop reading once that many records have been mapped.