在 C# 中,请说明如何利用 TaskCompletionSource 来控制一个 Task 的完成时机,并谈谈其底层工作原理及适用场景。
考察说明
考查对 TaskCompletionSource 机制的理解,以及如何用其包装异步操作实现自定义任务完成。
回答思路
- 【回答框架 1】TaskCompletionSource 是 .NET 中用于手动控制 Task 生命周期的类,通过其 Task 属性暴露一个可等待的任务。它允许在任意时刻调用 SetResult、SetException 或 SetCanceled 来使该任务进入完成状态。
- 【回答框架 2】其底层基于 Task 的状态机,通过 SetResult 或类似方法将任务状态迁移到 RanToCompletion、Faulted 或 Canceled。适用于桥接基于回调或事件的异步 API,如 EAP 模式,可以封装为基于 Task 的异步方法。
- 【回答框架 3】典型用法包括:创建一个 TaskCompletionSource 实例,将它的 Task 返回给调用方,在异步操作完成时调用 SetResult 或 SetException。注意避免同步阻塞,尽量使用 TrySet* 方法处理竞争条件。
- 【关键点 1】TaskCompletionSource 提供手动控制 Task 完成状态的能力。
- 【关键点 2】通过 TrySetResult 等方法安全地设置结果或异常。
- 【关键点 3】常用于将事件或回调转换为可等待的 Task。
- 【关键点 4】在 .NET 中与 async/await 无缝配合。
- 【易错点 1】不要对同一个 TaskCompletionSource 多次设置结果,会抛出异常。
- 【易错点 2】避免在异步操作完成时阻塞线程,应使用回调或异步方式。
- 【易错点 3】注意处理取消和超时场景,否则任务可能永远挂起。