Как лучше всего синхронизировать коллекцию объектов между различными потоками в .Net?
Мне нужен доступ к списку или словарю из разных потоков в поточно-безопасном режиме. С добавлением, удалением, по каждому элементу и т. д.
Согласовано. Одним из факторов является то, нужна ли вам коллекция со строгой типизацией.





Вы можете реализовать очередь без блокировки:
http://www.boyet.com/Articles/LockfreeQueue.html
Или обработайте синхронизацию самостоятельно, используя блокировки:
Hashtable.Synchronized метод возвращает синхронизированную (потокобезопасную) оболочку для Hashtable.
http://msdn.microsoft.com/en-us/library/system.collections.hashtable.synchronized(VS.80).aspx
Это также существует для других коллекций.
Некоторые классы коллекций в .Net имеют встроенную поддержку для синхронизации и обеспечения безопасного доступа из нескольких потоков. Например (в C++ / CLR):
Collections::Queue ^unsafe_queue = gcnew Collections::Queue();
Collections::Queue ^safe_queue = Collections::Queue::Synchronized(unsafe_queue);
Вы можете выбросить ссылку на unsafe_queue и оставить ссылку на safe_queue. Он может быть разделен между потоками, и вам гарантирован потокобезопасный доступ. Другие классы коллекций, такие как ArrayList и Hashtable, также поддерживают это аналогичным образом.
Не зная подробностей, я бы склонялся к делегатам и событиям, чтобы уведомлять об изменениях.
http://msdn.microsoft.com/en-us/library/17sde2xt(VS.71).aspx
И реализация паттерна Observer или Publish Subscribe
http://en.wikipedia.org/wiki/Observer_patternhttp://msdn.microsoft.com/en-us/library/ms978603.aspx
В основном это зависит от шаблона, который вам нужно использовать. Если у вас есть несколько потоков, записывающих и читающих одно и то же место, вы можете использовать ту же структуру данных, которую вы использовали бы с одним потоком (hastable, массив и т. д.) С блокировкой / монитором или ReaderWriterLock для предотвращения состояний гонки. В случае, если вам нужно передавать данные между потоками, вам понадобится какая-то очередь (синхронизированная или без блокировки), в которую поток (ы) группы A будет вставлять, а поток (ы) группы B будет удалять из. Вы можете использовать WaitEvent (AutoReset или Manual), чтобы не терять ЦП, когда очередь пуста. Это действительно зависит от того, какой рабочий процесс вы хотите достичь.
Возможно, вы захотите пояснить, что вы здесь пытаетесь сделать. Уже существующие ответы об очереди или хэш-таблице могут быть подходящими или не подходящими для вашей проблемы - с учетом того, что вы сказали, трудно сказать. Грубое описание проблемы может дать вам более подходящие ответы.