Skip to content

Commit

Permalink
Recover from "The array bounds are invalid." exception
Browse files Browse the repository at this point in the history
  • Loading branch information
kmaki565 committed Feb 25, 2024
1 parent e227aeb commit 7b7bd49
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions EventLook/Model/DataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ public interface IDataService
public class DataService : IDataService
{
private CancellationTokenSource cts;
const int WIN32ERROR_RPC_S_INVALID_BOUND = unchecked((int)0x800706C6);
public async Task<int> ReadEvents(LogSource logSource, DateTime fromTime, DateTime toTime, bool readFromNew, IProgress<ProgressInfo> progress)
{
using (cts = new CancellationTokenSource())
{
// Event records to be sent to the ViewModel
var eventRecords = new List<EventRecord>();
EventLogReader reader = null;
EventRecord eventRecord = null;
string errMsg = "";
int count = 0;
int totalCount = 0;
Expand All @@ -54,15 +56,36 @@ public async Task<int> ReadEvents(LogSource logSource, DateTime fromTime, DateTi
_ = Task.Run(() => totalCount = GetRecordCount(logSource));

reader = new EventLogReader(elQuery);
var eventRecord = reader.ReadEvent();
await Task.Run(() =>
{
for (; eventRecord != null; eventRecord = reader.ReadEvent())
int retryCount = 0;
while (true)
{
try
{
eventRecord = reader.ReadEvent();
}
catch (EventLogException ex)
{
// Workaround: ReadEvent can somehow throw an exception "The array bounds are invalid."
if (ex.HResult == WIN32ERROR_RPC_S_INVALID_BOUND && retryCount < 3 && eventRecord?.Bookmark != null)
{
reader.Seek(eventRecord.Bookmark, 1); // Reset the position to last successful read + 1.
reader.BatchSize /= 2; // Halve the 2nd param of EvtNext Win32 API to be called.
retryCount++;
Debug.WriteLine($"Retry #{retryCount}. Last successful-read event's RecordId: {eventRecord.RecordId}, Time: {eventRecord.TimeCreated}");
continue;
}
else
throw;
}
if (eventRecord == null) // No more records.
break;

cts.Token.ThrowIfCancellationRequested();

eventRecords.Add(eventRecord);
++count;
count++;
if (count % 100 == 0)
{
var info = new ProgressInfo(eventRecords.ConvertAll(e => new EventItem(e)), isComplete: false, isFirst, totalCount);
Expand Down Expand Up @@ -94,6 +117,7 @@ await Task.Run(() =>
{
var info_comp = new ProgressInfo(eventRecords.ConvertAll(e => new EventItem(e)), isComplete: true, isFirst, totalCount, errMsg);
progress.Report(info_comp);
eventRecord?.Dispose();
reader?.Dispose();
Debug.WriteLine("End Reading");
}
Expand Down

0 comments on commit 7b7bd49

Please sign in to comment.