Повторять сбор из разных потоков

#.net #multithreading

#.net #многопоточность

Вопрос:

У меня есть несколько потоков, которые добавляют, удаляют, выбирают из одного списка, и, очевидно, я получаю исключение: InvalidOperationException, потому что коллекция была изменена из-за другой операции. Итак, я понимаю, что это плохой дизайн моего кода и т.д. Здесь возникает вопрос: каков самый простой выход из такой ситуации, как я могу улучшить ситуацию, не переписывая весь код?

Ответ №1:

Если вам нужно только вставлять, обновлять и удалять одновременно, вы можете написать свою собственную реализацию IList<T> , которая объединяет обычный список и использует lock(...) для защиты всех операций чтения и записи (например, Contains, Add и т.д.).

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

Вы также могли бы рассмотреть возможность использования новых параллельных коллекций в .NET 4.0. Хотя их нет ConcurrentList<T> , вы можете использовать ConcurrentQueue<T> вместо этого.

Ответ №2:

Самый простой способ — использовать lock конструкцию, подобную этой:

 lock(myList)
{
    myList.Add(somevalue);
}
  

Это позволит одновременно обращаться к списку только 1 потоку. Для обеспечения безопасности вам понадобится lock везде, где вы используете список.

Комментарии:

1. хммм, просто небольшое объяснение этого механизма?

2. Это завершает класс C # Monitor, который разрешает только 1 поток одновременно через этот блок кода. Если два потока выполняют это утверждение одновременно, одному разрешается выполнить, а другой ожидает. Таким образом, доступ к списку может быть доступен только одному потоку в любой момент времени, и вы не должны получать исключение InvalidOperationException.

3. о, да, да, спасибо, просто не проснулся. Хорошо, спасибо, чувак, думаю, это сработает!