2009-03-10 5 views
0

Я изучаю (рассматривая возможность написания собственного словабельного словаря) Я нашел следующую реализацию.Словарь ThreadSafe ... Ключевые значения Перечисляемые пары? (.net)

http://devplanet.com/blogs/brianr/archive/2008/09/26/thread-safe-dictionary-in-net.aspx

Это выглядит довольно хорошо в целом, но есть одна вещь, которая меня смущает.

Невозможно перечислить словарь потоков. Вместо перечисления ключей или значений коллекции

, который находится в обоих

public virtual IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() 
{ 
    throw new NotSupportedException("Cannot enumerate a threadsafe dictionary. Instead, enumerate the keys or values collection"); 
} 


IEnumerator IEnumerable.GetEnumerator() 
{ 
    throw new NotSupportedException("Cannot enumerate a threadsafe dictionary. Instead, enumerate the keys or values collection"); 
} 

То, что я не получаю, почему это хорошо, чтобы перечислить ключи и значения, но не КВП-ые годы словаря?

Может ли кто-то пролить свет на это для меня? Заранее спасибо.

ответ

4

SO пользователь и работник MS JaredPar имеет короткую серию на своем блоге о строительстве потоко коллекции, которые, безусловно, стоит вашего времени:

[Обновление:]
Чтение через них снова, если у вас мало времени, вторая статья, вероятно, может стоять на ее собственном.

Резюмируя: большинство «потоки» коллекции вы найдете размещены в Интернете, как правило, либо не очень полезно или только потокобезопасную одну операции в это время, делая «решение» члены как .Count или .Contains бесполезных (они «несвежие» по время выполнения следующей строки кода).

1

Когда вы перечислите коллекцию KVP, вы погружаетесь в замок и выходите из него для всего словаря. Таким образом, в теле цикла вашего перечисления вы не находитесь в замке, и изменение KVP может привести к состоянию гонки.

1

Я могу ответить на этот вопрос непосредственно, так как я написал, что словарь :)

Получения нумератора на словаре получите ссылку на внутренние наборы KVP. Вам нужно будет удерживать блокировку чтения до тех пор, пока вы не закончите перечисление, что может быть длительным.

Поэтому я говорю, чтобы перечислить ключи и значения вместо этого, является то, что я копия список ключей и значений при запросе, поэтому я не возвращает ссылку на словари внутренний список, который, если вы изменили из-за блокировки, могут вызвать проблемы. Хотя, я полагаю, вы могли бы реализовать ту же модель на KVP, если хотите, так как они только для чтения.

public virtual ICollection<TKey> Keys 
    { 
     get 
     { 
      using (new ReadOnlyLock(this.dictionaryLock)) 
      { 
       return new List<TKey>(this.dict.Keys); 
      } 
     } 
    } 

    public virtual ICollection<TValue> Values 
    { 
     get 
     { 
      using (new ReadOnlyLock(this.dictionaryLock)) 
      { 
       return new List<TValue>(this.dict.Values); 
      } 
     } 
    } 
+0

Не могли бы вы также скопировать внутренний список? – Svish

+0

ahh, избили меня, –

+0

Настоящий трюк - это то, что вы все еще не могли использовать перечислитель, поскольку он является сдержанным. Если 2 потока попытались перечислить в одно и то же время, где бы вы сохранили скопированный список? –

Смежные вопросы