C#面试题更新 2026-08-03

请说明在 C# 中,如何对一个集合进行线程安全的遍历操作?

考察说明

考查对 C# 集合线程安全遍历的理解,包括同步机制、并发集合以及迭代期间的修改处理。

回答思路

  1. 【回答框架 1】线程安全遍历的核心问题是迭代过程中其他线程可能修改集合,导致异常或数据不一致。常用方法包括使用 lock 锁定集合,确保遍历期间不被打断,但会增加阻塞。
  2. 【回答框架 2】对于并发场景,推荐使用 System.Collections.Concurrent 命名空间下的并发集合,如 ConcurrentBag、ConcurrentDictionary 等,它们的迭代器返回集合的快照,不会抛出 InvalidOperationException,但可能不反映遍历开始后的修改。
  3. 【回答框架 3】对于普通集合,可以使用 ReaderWriterLockSlim 实现多读单写,允许遍历时并发读,写入时独占,但需注意升级锁的复杂性。
  4. 【回答框架 4】另一种方式是拷贝集合到数组或新集合,在副本上遍历,避免锁竞争,但会增加内存开销和拷贝时间。
  5. 【回答框架 5】选择哪种方式取决于遍历频率、修改频率和性能要求。遍历频繁而修改少可考虑快照;修改频繁且需要实时一致性则需锁或使用并发集合。
  6. 【关键点 1】使用锁(lock)可以保证遍历期间的一致性,但会降低并发性。
  7. 【关键点 2】并发集合的迭代器返回快照,不会因修改而抛异常。
  8. 【关键点 3】拷贝集合到副本再遍历可避免锁,但增加开销。
  9. 【关键点 4】ReaderWriterLockSlim 适合读多写少的场景。
  10. 【易错点 1】不要直接使用 foreach 遍历普通集合同时修改,会抛出 InvalidOperationException。
  11. 【易错点 2】锁的粒度不宜过大,否则性能下降。
  12. 【易错点 3】拷贝集合时注意深拷与浅拷的区别,避免修改引用对象造成副作用。