public CleanableWeakComHandleTable(int?cleanUpThreshold = null, TimeSpan?cleanUpTimeSlice = null) { _table = new Dictionary <TKey, WeakComHandle <TValue, TValue> >(); _deadKeySet = new HashSet <TKey>(); CleanUpThreshold = cleanUpThreshold ?? DefaultCleanUpThreshold; CleanUpTimeSlice = cleanUpTimeSlice ?? s_defaultCleanUpTimeSlice; _cleanUpState = CleanUpState.Initial; }
/// <summary> /// Cleans up references to dead objects in the table. This operation will return if it takes /// longer than <see cref="CleanUpTimeSlice"/>. Calling <see cref="CleanUpDeadObjects"/> further /// times will continue the process. /// </summary> public void CleanUpDeadObjects() { this.AssertIsForeground(); if (!_needsCleanUp) { return; } var timeSlice = new TimeSlice(CleanUpTimeSlice); if (_cleanUpState == CleanUpState.Initial) { _cleanUpEnumerator = _table.GetEnumerator(); _cleanUpState = CleanUpState.CollectingDeadKeys; } if (_cleanUpState == CleanUpState.CollectingDeadKeys) { if (_cleanUpEnumerator == null) { // The enumerator got reset while we were collecting dead keys. // Go ahead and remove the dead keys that were already collected before // collecting more. if (!RemoveDeadKeys(timeSlice)) { return; } _cleanUpEnumerator = _table.GetEnumerator(); } if (!CollectDeadKeys(timeSlice)) { return; } InvalidateEnumerator(); _cleanUpState = CleanUpState.RemovingDeadKeys; } if (_cleanUpState == CleanUpState.RemovingDeadKeys) { if (!RemoveDeadKeys(timeSlice)) { return; } _cleanUpState = CleanUpState.Initial; } _needsCleanUp = false; }