Skip to content

Commit 3c3adc5

Browse files
authored
Prevent cleanup timer callback from running during/after Dispose() (#25)
Prevent cleanup timer callback from running during/after Dispose() Closes #24.
1 parent 9c16c7d commit 3c3adc5

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

SqliteCache/SqliteCache.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,21 @@ public void Dispose()
6464
_logger.LogTrace("Disposing SQLite cache database at {SqliteCacheDbPath}", _config.CachePath);
6565

6666
// Dispose the timer first, because it might still access other things until it's been disposed!
67-
_cleanupTimer?.Dispose();
67+
if (_cleanupTimer is not null)
68+
{
69+
// Timer.Dispose(WaitHandle) ends up delegating to (the internal)
70+
// TimerQueueTimer.Dispose(WaitHandle), which calls (the private)
71+
// EventWaitHandle.Set(SafeWaitHandle) method, which is just a wrapper around Kernel32's
72+
// SetEvent() -- all of which is to say, we can't use a ManualResetEventSlim here.
73+
using var resetEvent = new ManualResetEvent(false);
74+
// If the timer has already been disposed, it'll return false immediately without setting the
75+
// event. Since we don't really protect against our own .Dispose() method being called twice
76+
// (maybe in a race), we should handle this eventuality.
77+
if (_cleanupTimer.Dispose(resetEvent))
78+
{
79+
resetEvent.WaitOne();
80+
}
81+
}
6882
Commands.Dispose();
6983

7084
_logger.LogTrace("Closing connection to SQLite database at {SqliteCacheDbPath}", _config.CachePath);

0 commit comments

Comments
 (0)