Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-28 13:51:42

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,涵盖了 **委托、泛型、异步编程、闭包、线程安全** 等多个高级语言特性,考察的是候选人对 C# 高级特性的理解和综合运用能力。

---

### 🧠 面试题:实现一个线程安全的异步事件总线(Event Bus)

#### 背景:

你正在开发一个多模块系统,模块之间需要通过事件进行通信。你决定实现一个轻量级的**线程安全、支持异步处理的事件总线(Event Bus)**,用于发布和订阅各种类型的事件。

---

### 💡 任务:

请使用 C# 实现一个名为 `AsyncEventBus` 的类,满足以下要求:

1. 支持订阅和取消订阅事件处理函数(`Func` 类型)。
2. 支持发布事件,并异步调用所有订阅了该事件类型的处理函数。
3. 所有订阅者处理事件时应**并行执行**(不阻塞彼此)。
4. 线程安全,支持并发发布和订阅操作。
5. 支持一次订阅(即订阅的处理函数只执行一次后自动取消订阅)。

---

### 📌 示例代码结构:

```csharp
public class AsyncEventBus
{
public void Subscribe(Func handler);
public void SubscribeOnce(Func handler);
public void Unsubscribe(Func handler);
public Task PublishAsync(TEvent @event);
}
```

---

### 🧪 使用示例:

```csharp
var bus = new AsyncEventBus();

bus.Subscribe(async e =>
{
await Task.Delay(100); // 模拟异步操作
Console.WriteLine($"Log: {e.Message}");
});

bus.SubscribeOnce(e =>
{
Console.WriteLine($"One-time handler: {e.Data}");
return Task.CompletedTask;
});

await bus.PublishAsync(new LogEvent("Hello"));
await bus.PublishAsync(new DataReceivedEvent("Important data"));

// 第二次发布时,DataReceivedEvent 的订阅者不应再被调用
await bus.PublishAsync(new DataReceivedEvent("More data")); // 不应输出
```

---

### ✅ 考察点:

| 考点 | 描述 |
|------|------|
| 泛型 | 能处理任意事件类型 |
| 委托和 Func | 使用 `Func` 处理异步逻辑 |
| 异步编程 | 使用 `Task` 和 `await` |
| 线程安全 | 使用线程安全的数据结构(如 `ConcurrentDictionary`, `Interlocked` 等) |
| 闭包与引用捕获 | 正确管理订阅和取消订阅 |
| 事件生命周期管理 | 实现 `SubscribeOnce` 功能 |
| 事件解耦设计 | 实现一个通用、解耦的事件通信机制 |

---

### 🧩 可选扩展(加分项):

- 支持事件处理函数的优先级(如按顺序执行)。
- 支持事件处理超时控制。
- 支持同步和异步混合处理(例如 `Action` 和 `Func` 兼容)。
- 支持日志记录或异常处理策略(如忽略异常、聚合异常等)。

---

如果你需要,我也可以提供一个参考实现 😊

是否需要我展示一种实现方式?

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

上一篇: c#题例-2025-07-28 19:25:11

下一篇: c#题例-2025-07-28 08:18:25

精华推荐