private void CancelExtracted(bool throwOnFirstException, SafeDictionary <CancellationTokenRegistration, Action> callbacks, bool ignoreDisposedException) { if (Interlocked.CompareExchange(ref _cancelRequested, 1, 0) == 0) { try { // The CancellationTokenSource may have been disposed jusst before this call _handle.Set(); } catch (ObjectDisposedException) { if (!ignoreDisposedException) { throw; } } UnregisterLinkedTokens(); List <Exception> exceptions = null; try { var id = _currentId; do { Action callback; var checkId = id; if (callbacks.Remove(id, registration => registration.Equals(checkId, this), out callback) && callback != null) { RunCallback(throwOnFirstException, callback, ref exceptions); } } while (id++ != int.MaxValue); } finally { // Whatever was added after the cancellation process started, it should run inline in Register... if they don't, handle then here. foreach ( var callback in callbacks.RemoveWhereKeyEnumerable(_ => true)) { RunCallback(throwOnFirstException, callback, ref exceptions); } } if (exceptions != null) { throw new AggregateException(exceptions); } } }
/// <summary> /// Removes the keys and associated values where the key satisfies the predicate. /// </summary> /// <param name="keyCheck">The predicate.</param> /// <returns> /// An <see cref="IEnumerable{TValue}" /> that allows to iterate over the values of the removed pairs. /// </returns> /// <remarks> /// It is not guaranteed that all the pairs of keys and associated values that satisfies the predicate will be removed. /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="keyCheck"/> is <c>null</c>.</exception> public IEnumerable <TValue> RemoveWhereKeyEnumerable(Predicate <TKey> keyCheck) { if (keyCheck == null) { throw new ArgumentNullException("keyCheck"); } return(_wrapped.RemoveWhereKeyEnumerable ( input => { TKey foundKey; if (PrivateTryGetValue(input, out foundKey)) { return keyCheck.Invoke(foundKey); } return false; } )); }