Необходим очень быстрый потокобезопасный сбор или дБ в памяти - PullRequest
2 голосов
/ 20 мая 2011

Я получаю данные из внешнего приложения:

class DataItem
{
   public string key;
   public int Attribute1;
   public string Attribute2;
}

Один поток хранит его в коллекции. Другие потоки (3-10) сбор запросов по ключу (90%) и атрибутам (10%).

Как лучше всего это реализовать, если у меня в коллекции 10, 100, 1000+ предметов?

Ответы [ 3 ]

4 голосов
/ 20 мая 2011

Если коллекция является неизменной (только для чтения, никогда не изменяется) после инициализации, и коллекция инициализируется до того, как к ней могут добраться какие-либо потоки, вам не нужно делать ничего особенного.Несколько потоков могут читать из коллекции или словаря одновременно без каких-либо проблем.

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

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

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

4 голосов
/ 20 мая 2011

Если вам действительно нужна база данных в памяти, то Sqlite с использованием управляемого поставщика данных будет вашим лучшим вариантом.Тем не менее, я подозреваю, что в этом случае вы будете в порядке с ConcurrenctDictionary .Эта коллекция может легко обрабатывать более 1000 элементов и множество потоков, обращающихся к ней параллельноПредостережение с использованием этой коллекции заключается в том, что вы можете указать только один ключ для каждой записи в коллекции.Возможно, вам придется использовать отдельные коллекции для каждого атрибута, который вы хотите найти.Опять же, если поиск по атрибуту достаточно редок, вы можете выбрать перечисление всей коллекции, чтобы найти соответствующие атрибуты без необходимости в отдельных коллекциях.

0 голосов
/ 20 мая 2011

Коллекция в памяти предназначена только для чтения? Это изменит то, что вы в конечном итоге используете.

Мои рекомендации -
Только для чтения : использовать ConcurrentDictionary
Чтение и запись : используйте DataSet

На мой взгляд, лучшей параллельной или поточно-ориентированной моделью будет DataSet - см .: ADO.Net Tackle Data Concurrency и MSDN DataSet . DataSet был разработан для хранения данных в памяти для нескольких клиентов. Обратите внимание, что MSDN говорит:

Этот тип безопасен для многопоточных операций read . Вы должны синхронизировать любые операции записи.

У вас есть альтернатива DataSet, как предлагает Брайан Гидеон, - ConcurrentDictionary.

С помощью DataReader вы можете заполнять пользовательские объекты, например DataItem, непосредственно из DataReader.

В любом случае оба эти решения обеспечат вам быстрый и одновременный доступ к данным в памяти.

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