C# имеет довольно хорошую модель коллекций, но класс ReadOnlyCollection является одним из наиболее унаследованных (или названных) классов во всей модели. Его следовало бы назвать «список только для чтения», а не сборку только для чтения.
Теперь, чтобы ответить на ваш вопрос, это всего лишь декоратор для чтения ILIST, поставляемый во время строительства. Поэтому код, который построил ReadOnlyCollection, может изменить исходный список со всеми вытекающими последствиями для многопоточного доступа.
Итак, перечисление через коллекцию было бы поточно-безопасным, если бы сборник был действительно readonly; но поскольку он не доступен только для чтения, он не является потокобезопасным. Учитывая объем репутации, который у вас есть, я уверен, что вам не интересно, почему перечисление через коллекцию, не предназначенную для чтения, не является потокобезопасной.
Что касается обходного пути, о котором вы просили, то вы можете либо использовать блокировку, либо вы можете пойти с принципом «lock-nothing» (или «lock-as-little-as-possible») и сделать подлинную копию только для чтения списка.
EDIT
Я перечитывал свой ответ много месяцев спустя, (спасибо-х asyncwait комментария,), и я понимаю, что я должен ответил на все вопросы Op без предположений, основанных на его репутации. Вероятно, ОП получил свой ответ, но я сделаю это ради будущих читателей.
Перечисление через коллекцию, не предназначенную для чтения, по своей сути не является потокобезопасной по тем же причинам, что даже в однопоточном сценарии вы не можете изменять коллекцию при ее перечислении. (ConcurrentModificationException в Java, InvalidOperationException в C#.) В однопоточном сценарии вы можете убедиться, что ваш код перечисления не пытается каким-либо образом изменить коллекцию, но в многопоточном сценарии один поток может перечислять коллекцию в то время как другой поток может изменять его одновременно.
О, мальчик. безопасные списки в .NET слишком долго. См. некоторые предыдущие обсуждения здесь: http://stackoverflow.com/questions/550616/lock -free-stack-and-queue-in-c-sharp и/или здесь: http://stackoverflow.com/questions/66622/threadsafe-foreach-enumeration-of-lists – Radu094