2015-03-17 4 views
-1

Это вопрос, который я выбрал, но мне было любопытно, что произойдет в следующей ситуации при использовании параллельного словаря и функциональности выхода.Использование урожайности с одновременным сбором

IEnumerable<int> GetValuesNotZero() 
{ 
    foreach(int value in dictionary.Values) 
    { 
     if(value != 0) 
     { 
      yield return value; 
     } 
    } 
} 

Если другой поток добавляет/удаляет/обновляет словарь, что произойдет со значениями в цикле foreach? Закрепляется ли словарь заблокированным во время его повторения, или я все еще рискую потерять добавленные/удаленные/обновленные значения?

ответ

2

Пока вы повторяете, если другой поток изменил словарь, вы найдете обновленные значения в отличие от исключения (с нормальным Dictionary<,>).

Если вы еще не достигли измененного элемента, вы в конце концов пройдете его; в противном случае вы можете пропустить обновленное значение, если вы уже посетили обновленный элемент.

От ConcurrentDictionary.GetEnumerator

Перечислитель вернулся из словаря является безопасным для использования одновременно с чтением и записью в словарь, однако это не представляет момент в срок снимок словаря. Содержимое , отображаемое через счетчик, может содержать модификации, сделанные , в словарь после вызова GetEnumerator.

Например, предположим, что Thread1 идет через словарь теперь в положении 3. Если Thread2 модифицированный элемент в позиции 7, вы найдете измененное значение. С другой стороны, если он изменил элемент в позиции 1, вы его не заметите. (Забудьте о том, что словарь неупорядочен, позиции используются для лучшего понимания).


Я просто понял, что ваш код перебирает Dictionary.Values (Спасибо @Svick за упоминание в комментариях); Ответ выше верен только в том случае, если вы зацикливаете словарь. Когда вы выполняете итерацию через свойство Values, вы фактически просматриваете моментальный снимок. Если словарь обновляется в среднем, вы его не заметите.

+0

Большое спасибо, это было именно то, что я искал! – ShaffDaddy

+0

Но код, о котором идет речь, не итерирует словарь, он выполняет итерацию 'Ценности'. – svick

+0

@svick Спасибо. Обновлен мой ответ. Оказывается, свойство 'Values' просто возвращает моментальный снимок. –