private bool ProcessDeadQueue(TimeSlice timeSlice) { Debug.Assert(_cleanupEnumerator == null, "We should never process dead queue when enumerator is alive."); while (_deadQueue.Count > 0) { var key = _deadQueue.First(); _deadQueue.Remove(key); Debug.Assert(_elements.ContainsKey(key), "How come the key is in the dead queue, but not in the dictionary?"); _elements.Remove(key); if (timeSlice.IsOver) { return false; } } return true; }
public void CleanupWeakComHandles() { if (!_needCleanup) { return; } var timeSlice = new TimeSlice(s_timeSliceForFileCodeModelCleanup); if (_state == State.Initial) { _cleanupEnumerator = _elements.GetEnumerator(); _state = State.Checking; } if (_state == State.Checking) { if (_cleanupEnumerator == null) { // The enumerator got reset while we were checking, need to process dead queue // before starting checking over again if (!ProcessDeadQueue(timeSlice)) { // Need more time to finish processing dead queue, continue next time return; } _cleanupEnumerator = _elements.GetEnumerator(); } if (!CheckWeakComHandles(timeSlice)) { // Need more time to check for dead elements, continue next time return; } // Done with checking, now process dead queue InvalidateEnumerator(); _state = State.ProcessingDeadQueue; } if (_state == State.ProcessingDeadQueue) { if (!ProcessDeadQueue(timeSlice)) { // Need more time to finish processing dead queue, continue next time return; } // Done with cleanup _state = State.Initial; _needCleanup = false; } }
private bool CheckWeakComHandles(TimeSlice timeSlice) { Debug.Assert(_cleanupEnumerator != null); Debug.Assert(_state == State.Checking); while (_cleanupEnumerator.MoveNext()) { if (!_cleanupEnumerator.Current.Value.IsAlive()) { _deadQueue.Add(_cleanupEnumerator.Current.Key); } if (timeSlice.IsOver) { return false; } } return true; }