2013-11-29 2 views
2

Сначала я думал, что «это хэш-тип данных, а затем он несортирован».Сортировка ConcurrentDictionary имеет смысл?

Затем, когда я собирался его использовать, я подробно изучил вопрос и выяснил, что этот класс реализует IEnumerable, а также this post подтвердил, что можно перебирать данные такого типа.

Итак, мой вопрос: если я использую foreach над ConcurrentDictionary, который является порядком, в котором я читал элементы?

Затем, в качестве второго вопроса, я хотел бы знать, имеют ли методы сортировки, унаследованные его интерфейсами, любое использование. Если я вызову метод сортировки по ConcurrentDictionary, новый порядок будет сохраняться (например, для входящего foreach).

Надежда Я сделал себе ясно

ответ

6

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

Таким образом, ваш код не должен зависеть от этого заказа.

От Dictionary<TKey, TValue>msdn docs:

Порядок, в котором элементы будут возвращены не определено.

(я не смог найти никаких ссылок относительно ConcurrentDictionary, но применяется тот же принцип.)

Когда вы смотрите «методы сортировки наследуются его интерфейсами», вы имеете в виду расширения LINQ? Мне нравится OrderBy? Если это так, эти расширения являются чисто функциональными и всегда возвращают новую коллекцию. Итак, чтобы ответить на ваш вопрос «новый порядок будет сохраняться?»: Нет, не будет. Однако вы можете использовать его следующим образом:

foreach(KeyValuePair<T1, T2> kv in dictionary.OrderBy(...)) 
{ 

} 
+0

Да, я имел в виду расширение LINQ и о да, черт, я слишком быстро читал эту вещь и не заботился о типе возврата. Спасибо за ваше объяснение. Поэтому я могу заявить, что итерация по ConcurrentDictionary в определенном порядке возможна только с использованием упорядоченного набора данных, который указывает на ключи. – Leggy7

0

Похоже, что вы можете просить о неприятностях, если вы не особенно осторожны. Как уже упоминалось, dcastro порядок элементов не обеспечивается. Более сложной проблемой является то, что ConcurrentDictionary может быть изменен в любое время другими потоками. Это означает, что даже если заказ был обеспечен, нет никаких причин, по которым новые элементы, добавляемые при повторении, не будут пропущены. Если вы не знаете, что можете запретить другим низам менять словарь, вероятно, не рекомендуется перебирать его.

+1

Реализация 'ConcurrentDictionary'' GetEnumerator' возвращает моментальный снимок словаря. Похоже на его копию. Таким образом, можно безопасно перечислять все коллекции в пространстве имен 'System.Collections.Concurrent'. – dcastro

+1

Просто для исправления моего предыдущего комментария: после просмотра исходного кода реализация не возвращает моментальный снимок словаря - «Содержимое, отображаемое через счетчик, может содержать изменения, внесенные в словарь после вызова GetEnumerator». Но все равно можно перечислить: «Перечислитель безопасен для одновременного использования с чтением и записью в стек» Исходный код: http://goo.gl/sU7d8f – dcastro

+0

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

1

если я использую foreach над ConcurrentDictionary, который является порядком, в котором я читал элементы?

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

Я хотел бы знать, являются ли методы сортировки, унаследованные его интерфейсами , любого вида использования.Если я вызову метод сортировки над ConcurrentDictionary, новый порядок будет сохраняться (например, для входящих foreach) ?.

Я предполагаю, что вы отсылая к методу OrderBy() расширения на интерфейсе IEnumnerable<KeyValuePair<TKey, TValue>>. Ничего не останется. Этот метод возвращает другой IEnumnerable<KeyValuePair<TKey, TValue>>. Словарь остается таким, каким он есть.

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

  • Нет связанных вопросов^_^