c#题例-2025-07-12 08:32:20
日期: 2025-07-12 分类: AI写作 63次阅读
当然可以!下面是一道**专家级别**的 C# 逻辑面试题,涉及 **委托、事件、闭包、异步编程和线程安全** 的综合理解:
---
### 🧠 面试题:分析并修复以下代码中的潜在问题
```csharp
using System;
using System.Threading.Tasks;
class Program
{
public static event EventHandler SimpleEvent;
static async Task Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
int capture = i;
SimpleEvent += (sender, e) =>
{
Console.WriteLine($"Handler {capture} invoked on thread {Environment.CurrentManagedThreadId}");
};
await Task.Run(() =>
{
SimpleEvent?.Invoke(null, EventArgs.Empty);
});
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
```
---
### ✅ 面试要求:
1. **解释这段代码本意是什么?**
2. **指出其中至少三个潜在问题或隐患(包括但不限于线程安全、闭包陷阱、事件内存泄漏等)?**
3. **如何修改代码以解决这些问题?**
---
### 💡 提示关键词:
- 捕获变量(captured variable)与闭包陷阱
- 多线程中访问 UI 或共享资源
- `event` 的线程安全性
- 异步调用中未取消订阅可能导致内存泄漏
- `Invoke` 是否在正确的上下文执行(如 UI 线程)
---
### 📌 参考答案概要(供面试官参考):
#### 1. 代码意图:
该程序试图注册多个事件处理函数,并在异步任务中触发这些处理函数。期望输出是每个 handler 打印出对应的编号和线程 ID。
#### 2. 存在的问题:
| 问题 | 描述 |
|------|------|
| **闭包捕获陷阱** | 使用了循环变量 `i`,没有正确使用局部副本 `capture = i`,可能导致所有 handler 输出相同的值(尽管这里用了 capture,但仍然要注意是否真的解决了问题)。 |
| **线程不安全地访问控制台** | 多个线程同时调用 `Console.WriteLine`,虽然不是致命错误,但在某些环境中会导致输出混乱。 |
| **事件未取消订阅** | 所有 handler 始终添加到静态事件中,可能导致内存泄漏(尤其是如果对象生命周期较长时)。 |
| **未处理异常和空事件** | 虽然使用了 `SimpleEvent?.Invoke(...)`,但如果 handler 中抛出异常会影响后续 handler 的执行。 |
| **事件处理逻辑可能在非预期上下文中运行** | 如果未来这个事件用于 UI 场景,那么 handler 应该调度回 UI 线程。 |
#### 3. 改进后的代码示例:
```csharp
using System;
using System.Threading.Tasks;
class Program
{
public static event EventHandler SimpleEvent;
static async Task Main(string[] args)
{
var handlers = new Action
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:AI写作
精华推荐