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

请说明在 C# 中实现线程安全事件的具体方法和注意事项。

风险判断技术原理C#

考察说明

考察对 C# 事件机制及多线程并发访问安全性的理解。

回答思路

  1. 【回答框架 1】在 C# 中,事件本质是多播委托,调用事件即调用其调用列表。线程安全的关键在于确保读取和调用事件时不会因并发修改而抛出异常。
  2. 【回答框架 2】常见做法是在触发事件前先将事件引用复制到局部变量,如 var handler = MyEvent; 然后调用 handler?.Invoke(...),这样即使其他线程在调用期间取消订阅,也不会影响当前调用。
  3. 【回答框架 3】更严格的做法是使用锁(如 lock 语句)保护事件的订阅和取消订阅操作,确保对事件的修改是原子的。或者使用同步上下文(如 SynchronizationContext)将事件触发和订阅封送到特定线程,避免并发访问。
  4. 【回答框架 4】也可以使用事件访问器(add/remove)来显式实现线程安全的订阅和取消订阅,例如使用锁或 Interlocked 操作。
  5. 【回答框架 5】对于需要保证事件通知顺序或避免阻塞的场景,可以考虑使用生产者-消费者模式或异步事件处理,但需注意上下文同步。
  6. 【关键点 1】事件是委托,调用前复制引用可避免空引用和并发修改异常。
  7. 【关键点 2】使用锁或 Interlocked 保护 add/remove 访问器可实现原子操作。
  8. 【关键点 3】事件触发时使用 ?.Invoke 可安全处理无订阅者情况。
  9. 【易错点 1】不要直接用 event 关键字而不加任何同步机制,因为默认的 add/remove 不是线程安全的。
  10. 【易错点 2】复制事件引用时,如果不使用局部变量,直接触发 event?.Invoke() 可能导致竞态条件。
  11. 【易错点 3】使用锁时注意避免死锁,不要长期持有锁。