#.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. о, да, да, спасибо, просто не проснулся. Хорошо, спасибо, чувак, думаю, это сработает!