Каков наилучший способ синхронизировать коллекцию объектов между различными потоками в .Net? - PullRequest
1 голос
/ 18 сентября 2008

Каков наилучший способ синхронизации коллекции объектов между различными потоками в .Net?

Мне нужно иметь доступ к списку или словарю из разных потоков в безопасном режиме. С добавлением, удалением, Foreachs и т. Д.

Ответы [ 5 ]

1 голос
/ 20 сентября 2008

В основном это зависит от шаблона, который вам нужно использовать. Если у вас есть несколько потоков, пишущих и читающих одно и то же место, вы можете использовать ту же структуру данных, которую вы использовали бы с одним потоком (hastable, array и т. Д.) С блокировкой / монитором или ReaderWriterLock, чтобы предотвратить состояние гонки. В случае, если вам нужно передать данные между потоками, вам понадобится какая-то очередь (синхронизированная или без блокировки), в которую поток (ы) группы A будет вставлять, а поток (ы) группы B будет удалять из нее. Возможно, вы захотите использовать WaitEvent (AutoReset или Manual), чтобы не потерять процессор, когда очередь пуста. Это действительно зависит от того, какой рабочий процесс вы хотите достичь.

0 голосов
/ 18 сентября 2008

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

http://msdn.microsoft.com/en-us/library/17sde2xt(VS.71).aspx

И реализация шаблона Observer или Publish Subscribe

http://en.wikipedia.org/wiki/Observer_pattern http://msdn.microsoft.com/en-us/library/ms978603.aspx

0 голосов
/ 18 сентября 2008

Hashtable.Synchronized метод возвращает синхронизированную (потокобезопасную) оболочку для Hashtable.

http://msdn.microsoft.com/en-us/library/system.collections.hashtable.synchronized(VS.80).aspx

Это также существует для других коллекций.

0 голосов
/ 18 сентября 2008

Некоторые классы коллекций в .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, также поддерживают это аналогичным образом.

0 голосов
/ 18 сентября 2008

Вы можете реализовать очередь без блокировки:

http://www.boyet.com/Articles/LockfreeQueue.html

Или обработайте синхронизацию самостоятельно, используя блокировки:

http://www.albahari.com/threading/part2.html#_Locking

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