Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-08-08 21:58:29

当然可以!下面是一道**专家级别**的 C# 逻辑面试题,它考察了对 **委托、事件、异步编程、闭包捕获、线程安全** 和 **设计模式** 的综合理解能力:

---

### 🧠 面试题:异步事件订阅陷阱与线程安全处理

#### 情境描述:

你正在开发一个多线程的事件驱动系统,其中有一个事件发布者 `EventPublisher`,它可以周期性地在后台线程上发布事件。多个订阅者(`EventSubscriber`)可以订阅这个事件,并在事件触发时执行异步操作。

为了模拟这个系统,你编写了如下代码:

```csharp
class Program
{
static async Task Main(string[] args)
{
var publisher = new EventPublisher();

for (int i = 0; i < 5; i++)
{
var subscriber = new EventSubscriber(i);
publisher.OnEvent += subscriber.HandleEvent;
}

publisher.Start();

Console.WriteLine("Press any key to exit.");
Console.ReadKey();

publisher.Stop();
}
}

public class EventPublisher
{
public event Func OnEvent;

private CancellationTokenSource _cts = new();
private readonly object _lock = new();

public void Start()
{
Task.Run(async () =>
{
while (!_cts.IsCancellationRequested)
{
await Task.Delay(1000);

// 🔥 问题点:这里可能引发异常或线程安全问题
if (OnEvent != null)
{
await OnEvent();
}
}
}, _cts.Token);
}

public void Stop()
{
_cts.Cancel();
}
}

public class EventSubscriber
{
private int _id;

public EventSubscriber(int id)
{
_id = id;
}

public async Task HandleEvent()
{
await Task.Delay(500); // 模拟耗时操作
Console.WriteLine($"Subscriber {_id} handled event on thread {Thread.CurrentThread.ManagedThreadId}");
}
}
```

---

### 🧩 面试问题:

1. **这段代码存在哪些潜在的问题?**
2. **为什么 `OnEvent != null` 的判断可能不安全?**
3. **如何修改 `OnEvent` 的调用方式以确保线程安全?**
4. **`HandleEvent` 是异步方法,直接作为事件处理程序使用会有什么后果?**
5. **如果多个线程同时取消订阅(`OnEvent -= ...`),是否线程安全?**
6. **你如何改进这段代码以使其在高并发、多线程环境下安全、可靠地运行?**

---

### 🧪 附加挑战(可选):

- 如果你希望支持事件处理失败后自动重试机制,你会如何设计?
- 如果你希望限制并发处理事件的订阅者数量(例如最多同时执行3个),你会如何实现?

---

### 💡 参考答案方向(提示):

1. **空引用问题**:`if (OnEvent != null)` 在多线程环境下可能在判断后事件被置为 null,导致 NullReferenceException。
2. **线程安全访问事件**:应使用局部变量缓存事件委托(`var handler = OnEvent`)。
3. **异步事件调用**:应并发调用所有订阅者并等待全部完成,使用 `Task.WhenAll()`。
4. **线程安全的事件实现**:可使用 `EventHandlerList` 或 `lock` 保护事件的添加/移除。
5. **取消订阅安全**:C# 的 `+=` 和 `-=` 是原子操作,但事件链本身不是线程安全的,仍需保护。
6. **改进方式**:引入 `async/await` 安全模式、并发控制、线程同步机制等。

---

如果你需要,我也可以提供一份**优化后的完整实现代码**作为参考。

是否需要?✅

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

上一篇:无

下一篇: c#题例-2025-08-08 16:25:12

精华推荐