Как уже сказал Джон, трудно дать вам хороший ответ.
Очевидный поиск в Google приводит к: http://www.codeproject.com/KB/cs/safe_enumerable.aspx
Идея заключается в том, чтобы заблокировать экземпляр IEnumerable в конструкции, которая имеет серьезные недостатки.
Следующая очевидная вещь - это изоляция, когда вы создаете копию своей структуры и перебираете копию. Это если наивно реализовано очень много памяти, но это может стоить того, если ваш набор данных относительно мал.
Лучше всего, если ваши данные неизменны, тогда у вас есть автоматическая защита потоков, но если вы привязаны к коллекции, число которых действительно изменяется, у вас есть изменяемая структура данных. Если бы вы могли изменить структуру данных в неизменную, все готово.
Поскольку блокировка данных на долгое время не очень хорошая идея, вы можете реализовать стратегии, обеспечивающие безопасность потоков, когда вы используете точную структуру данных и пример использования. Если вы, например, редко изменяете данные и часто перечисляете их, вы можете реализовать оптимистическое перечисление, которое читает перед началом перечисления счетчик записи вашей структуры данных и выдает результаты, как обычно. Если между ними происходит запись, вы можете выдать исключение, чтобы дать сигнал пользователю вашего перечислителя повторить попытку, пока он не преуспеет. Это работает, но передает делегату вашего перечислителя ответственность за то, что он должен повторить перечисление, пока оно не будет успешно выполнено.