internal void EnableExpirationTimer(bool enable) { if (enable) { if (_timerHandleRef == null) { DateTime utcNow = DateTime.UtcNow; TimeSpan due = _tsPerBucket - (new TimeSpan(utcNow.Ticks % _tsPerBucket.Ticks)); Timer timer = new Timer(new TimerCallback(this.TimerCallback), null, due.Ticks / TimeSpan.TicksPerMillisecond, _tsPerBucket.Ticks / TimeSpan.TicksPerMillisecond); _timerHandleRef = new GCHandleRef <Timer>(timer); Dbg.Trace("Cache", "Cache expiration timer created."); } } else { GCHandleRef <Timer> timerHandleRef = _timerHandleRef; if (timerHandleRef != null && Interlocked.CompareExchange(ref _timerHandleRef, null, timerHandleRef) == timerHandleRef) { timerHandleRef.Dispose(); Dbg.Trace("Cache", "Cache expiration timer disposed."); while (_inFlush != 0) { Thread.Sleep(100); } } } }
internal void EnableExpirationTimer(bool enable) { if (enable) { if (_timerHandleRef == null) { DateTime utcNow = DateTime.UtcNow; TimeSpan due = _tsPerBucket - (new TimeSpan(utcNow.Ticks % _tsPerBucket.Ticks)); Timer timer; // Don't capture the current ExecutionContext and its AsyncLocals onto the timer causing them to live forever bool restoreFlow = false; try { if (!ExecutionContext.IsFlowSuppressed()) { ExecutionContext.SuppressFlow(); restoreFlow = true; } timer = new Timer(new TimerCallback(this.TimerCallback), null, due.Ticks / TimeSpan.TicksPerMillisecond, _tsPerBucket.Ticks / TimeSpan.TicksPerMillisecond); } finally { // Restore the current ExecutionContext if (restoreFlow) { ExecutionContext.RestoreFlow(); } } _timerHandleRef = new GCHandleRef <Timer>(timer); Dbg.Trace("Cache", "Cache expiration timer created."); } } else { GCHandleRef <Timer> timerHandleRef = _timerHandleRef; if (timerHandleRef != null && Interlocked.CompareExchange(ref _timerHandleRef, null, timerHandleRef) == timerHandleRef) { timerHandleRef.Dispose(); Dbg.Trace("Cache", "Cache expiration timer disposed."); while (_inFlush != 0) { Thread.Sleep(100); } } } }
public void Dispose() { if (Interlocked.Exchange(ref _disposed, 1) == 0) { lock (_timerLock) { GCHandleRef <Timer> timerHandleRef = _timerHandleRef; if (timerHandleRef != null && Interlocked.CompareExchange(ref _timerHandleRef, null, timerHandleRef) == timerHandleRef) { timerHandleRef.Dispose(); Dbg.Trace("MemoryCacheStats", "Stopped CacheMemoryTimers"); } } while (_inCacheManagerThread != 0) { Thread.Sleep(100); } _cacheMemoryMonitor?.Dispose(); // Don't need to call GC.SuppressFinalize(this) for sealed types without finalizers. } }