Словарь ThreadSafe ... Пары ключей значения Перечислимые? (.сеть) - PullRequest
0 голосов
/ 10 марта 2009

Я просматривал (рассматривая написание своего собственного многобезопасного словаря), я нашел следующую реализацию.

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");
}

Чего я не понимаю, так это то, почему можно перечислять ключи или значения, но не kvp-значения словаря?

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

Ответы [ 3 ]

4 голосов
/ 10 марта 2009

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

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

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

2 голосов
/ 25 марта 2009

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

Получив перечислитель в словаре, вы получите ссылку на внутренние наборы 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);
            }
        }
    }
1 голос
/ 10 марта 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...