The primary purpose of this PR is to make the EventLogger and SpecStore classes thread safe, and as part of that work I also converted the old timer-based periodic task logic to instead use traditional tasks with delays. Here are the main features of the work covered in this PR:
Timer-based logic now uses long running Tasks that terminate in response to a CancellationToken
EventLogger uses a simple lock to guard all access to the _eventLogQueue and _errorsLogged fields.
SpecStore uses a ReaderWriterLock to guard access to the _idLists. This allows parallel evaluation of conditions that need to reference the ID lists, but writes are synchronized.
A small handful of other miscellaneous fixes, including defensively guarding against some possible NullReferenceExceptions, simplifying HashSet Contains/Add logic, and avoiding modifying a dictionary while iterating through it.
The primary purpose of this PR is to make the
EventLogger
andSpecStore
classes thread safe, and as part of that work I also converted the old timer-based periodic task logic to instead use traditional tasks with delays. Here are the main features of the work covered in this PR:EventLogger
uses a simple lock to guard all access to the_eventLogQueue
and_errorsLogged
fields.SpecStore
uses a ReaderWriterLock to guard access to the_idLists
. This allows parallel evaluation of conditions that need to reference the ID lists, but writes are synchronized.NullReferenceExceptions
, simplifying HashSet Contains/Add logic, and avoiding modifying a dictionary while iterating through it.