Хотя ответ на this question превосходный, это означает, что вы должны окружать вызовы List.ToArray() в блокировке для параллелизма. this blog post также подразумевает, что он может катастрофически (но редко). Обычно я использую ToArray вместо блокировки при перечислении списков или других коллекций, чтобы исключить исключение «Collection Modified, Enumeration not complete». Этот ответ и сообщение в блоге вызвали это предположение.Может ли ToArray() выдавать исключение?
Документация для List.ToArray() не содержит никаких исключений, поэтому я всегда предполагал, что она всегда будет завершена (хотя, может быть, с устаревшими данными) и что, хотя она не является потокобезопасной с точки зрения согласованности данных , он является потокобезопасным с точки зрения выполнения кода - другими словами, он не будет генерировать исключение, и вызов его не повредит внутреннюю структуру данных базовой коллекции.
Если это предположение неверно, то, хотя оно никогда не вызывало проблемы, это может быть временная бомба в приложении с высокой степенью готовности. Каков окончательный ответ?
Список .Add также не генерирует исключение, если отдельные темы изменяют список одновременно. Он по-прежнему не является потокобезопасным. Он просто проверяет, что вы не изменяете и не перечисляете его одновременно в одном и том же потоке. Почему вы считаете, что метод, который не документирован как потокобезопасный, может быть потокобезопасным? (Предполагается, что вы говорите о списке .ToArray или Enumerable.ToArray. ConcurrentBag .ToArray потокобезопасно, как перечислив ConcurrentBag без ToArray.) –
dtb
я сузили сферу вопроса, чтобы сосредоточить внимание на список и список так как это те, кого меня больше всего волнует. Я видел эту технику, используемую во многих популярных фреймворках с открытым исходным кодом, поэтому я не думаю, что я единственный, кто делает предположение о «безопасности» этой техники. Я не спрашиваю, являются ли они потокобезопасными (по определению это не так), но я должен начать поиск и исправление любых случаев «небезопасных» вызовов ToArray()? –
Вы уверены, что эти рамки с открытым исходным кодом используют ToArray, а не блокировку, или они фактически используют ToArray для изменения списка, когда они перечисляют его в том же потоке? – dtb