Блокировка потоков / эксклюзивные улучшения доступа - PullRequest
1 голос
/ 31 марта 2011

У меня есть 2 многопоточных метода, работающих в 2 разных местах, но в то же время разделяющих доступ к объекту массива списка (назовем его PriceArray ), первый поток Добавляет и При необходимости удаляет элементов из PriceArray (содержимое массива обновляется сторонним поставщиком данных), а средняя частота обновления составляет от 0,5 до 1 секунды.

Второй поток только читает -на данный момент - содержимое массива каждые 3 секунды с использованием цикла foreach (принимает большинство элементов, но не все).

Чтобы избежать неприятного исключения Collection was modified; enumeration operation may not execute, когда второй поток проходит через массив Iзаключили операцию добавления и удаления в первый поток с lock(PriceArray), чтобы обеспечить исключительный доступ и предотвратить возникновение этого исключения.Проблема в том, что я заметил проблему с производительностью, когда второй метод пытается циклически перебрать элементы массива, так как большую часть времени массив блокируется потоком добавления / удаления.

Если сценарий выполняется таким образом, выполнитеу вас есть какие-либо предложения, как улучшить производительность, используя другие методы обеспечения безопасности потоков / эксклюзивного доступа в C # 4.0?

Спасибо.

Ответы [ 2 ]

1 голос
/ 14 июня 2011

Мое предложение заключается в том, что ArrayList.Remove () занимает большую часть времени, потому что для выполнения удаления он выполняет две дорогостоящие вещи:

  1. линейный поиск: просто берет элементы один за другим и сравнивает с удаляемым элементом
  2. когда найден индекс удаляемого элемента - он сдвигает все под ним на одну позицию влево.

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

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

1 голос
/ 31 марта 2011

Да, есть много альтернатив.

Лучше всего / проще всего было бы перейти на использование соответствующей коллекции в System.Collections.Concurrent. Это все поточно-ориентированные коллекции, которые позволят вам использовать их без управления своими собственными блокировками. Как правило, они либо не содержат блокировок, либо используют очень тонкозернистую блокировку, поэтому, вероятно, значительно улучшат влияние на производительность, которое вы получаете от синхронизации.

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

...