Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-08-02 20:58:41

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,涉及 **委托、泛型、异步编程、闭包捕获、线程安全**等多个高级概念,适合考察候选人对 C# 高级特性的理解和实际应用能力。

---

### 🧠 面试题:异步委托链与线程安全陷阱

#### 问题描述:

你被要求实现一个异步任务调度器 `AsyncTaskScheduler`,它支持注册多个异步任务(`Func>` 类型),并按顺序执行它们。每个任务都应该在指定的延迟后启动(由任务注册时提供),并且所有任务的返回值需要被汇总,最后返回一个总和。

此外,该调度器需要满足以下要求:

1. **支持异步等待所有任务完成**(即提供一个 `Task GetTotalResultAsync()` 方法返回最终的总和)。
2. **每个任务应在指定延迟后启动**(例如延迟 100ms 后才开始执行)。
3. **支持取消操作**(通过传入的 `CancellationToken` 可以取消所有任务)。
4. **线程安全**:多个线程可能同时注册任务,也可能会取消任务。
5. **避免闭包捕获陷阱**。

---

### 💡 示例代码结构(需要你实现):

```csharp
public class AsyncTaskScheduler
{
public void RegisterTask(Func> taskFactory, TimeSpan delay)
{
// TODO: 实现注册逻辑
}

public Task GetTotalResultAsync()
{
// TODO: 返回一个 Task,表示所有任务的总和
}

public void Cancel()
{
// TODO: 取消所有正在等待或执行的任务
}
}
```

---

### ✅ 示例使用方式:

```csharp
var scheduler = new AsyncTaskScheduler();
var cts = new CancellationTokenSource();

// 注册多个异步任务
scheduler.RegisterTask(async token =>
{
await Task.Delay(200, token);
return 10;
}, TimeSpan.FromMilliseconds(100));

scheduler.RegisterTask(async token =>
{
await Task.Delay(300, token);
return 20;
}, TimeSpan.FromMilliseconds(150));

// 启动并获取结果
int total = await scheduler.GetTotalResultAsync();
Console.WriteLine($"Total: {total}");

// 取消
cts.Cancel();
```

---

### 🧪 考察点:

- **异步委托链的组织方式**(如何按延迟启动任务)
- **线程安全设计**(并发注册任务)
- **闭包捕获与变量生命周期问题**
- **CancellationToken 的正确使用**
- **TaskCompletionSource 的使用**
- **延迟任务调度(可使用 `Task.Delay` 或 `Timer`)**
- **异常处理和任务取消的统一处理**

---

### 📌 提示:

- 可以使用 `ConcurrentBag` 或 `List` + 锁来保存任务。
- 使用 `Task.Delay(delay).ContinueWith(...)` 来实现延迟启动。
- 使用 `TaskCompletionSource` 来统一多个任务的结果。
- 注意:不要在 lambda 中直接捕获循环变量或延迟变量,避免闭包陷阱。
- 考虑使用 `Interlocked` 或 `lock` 来保证计数器/状态同步。

---

如果你需要,我也可以提供参考实现或逐步解析这道题。是否需要?

除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog

上一篇: c#题例-2025-08-03 02:32:02

下一篇: c#题例-2025-08-02 15:25:20

精华推荐