请阐述 C# 中 CountdownEvent 的用途,并说明在多线程任务协同中如何借助它实现线程同步。
考察说明
考察对 CountdownEvent 这一并发原语的理解及实际应用能力。
回答思路
- 【回答框架 1】CountdownEvent 是 C# 中用于线程同步的同步原语,它维护一个计数,当计数减到零时,所有等待该事件的线程被唤醒。主要用于等待多个任务或线程完成后再继续执行的场景。
- 【回答框架 2】在多线程任务中使用时,首先创建 CountdownEvent 实例并指定初始计数,该计数通常等于需要等待的任务数。每个任务完成后调用 Signal 方法将计数减一。主线程或其他等待线程调用 Wait 方法阻塞,直到计数为零。
- 【回答框架 3】CountdownEvent 提供了 Reset 方法,可以将计数重新设置为初始值,便于复用。还支持 Wait 方法的超时和取消令牌参数,允许等待操作在指定时间内或取消时返回,避免无限期阻塞。
- 【回答框架 4】与 ManualResetEventSlim 和 SemaphoreSlim 等其他同步原语相比,CountdownEvent 专门用于等待所有参与的线程完成,其计数递减机制更直接。它不要求等待方必须持有锁或指定超时,使用起来更简洁。
- 【关键点 1】CountdownEvent 用于等待所有指定任务完成,计数归零触发等待者继续。
- 【关键点 2】任务完成时调用 Signal 减少计数,等待线程通过 Wait 阻塞。
- 【关键点 3】Reset 方法支持计数重置,实现复用。
- 【关键点 4】CountdownEvent 支持超时和取消令牌,避免无限阻塞。
- 【关键点 5】与 ManualResetEventSlim 相比,CountdownEvent 适合等待 N 个任务完成。
- 【易错点 1】计数初始值必须与实际任务数匹配,否则可能导致等待过早或永久阻塞。
- 【易错点 2】多次调用 Signal 可能会使计数低于零,需确保每次 Signal 对应一次任务完成。
- 【易错点 3】在等待线程与任务线程之间需正确协调,防止 CountdownEvent 在任务开始前被重置,导致逻辑错误。