贝利信息

c# C# 中如何处理硬件中断和高精度计时器

日期:2026-01-14 00:00 / 作者:煙雲
C#无法直接响应硬件中断,因运行在用户态托管环境,需依赖驱动将中断转为事件;Stopwatch是唯一可靠高精度计时器,基于HPET/TSC;硬实时场景必须绕过.NET用C/C++驱动或实时系统。

Windows 上 C# 无法直接响应硬件中断

C# 运行在 .NET 运行时之上,属于用户态托管环境,Windows 内核禁止用户程序直接注册或响应 IRQ(如键盘、串口、PCIe 设备触发的硬件中断)。你看到的“中断处理”实际是驱动层把中断转为事件(如 WaitForSingleObject 可等待的内核对象),再由 Win32 API 或 .NET 封装暴露为回调——C# 本身不接触中断向量表或 IRET 指令。

如果你需要对接物理设备(如工业传感器、FPGA 卡),必须依赖:

Stopwatch 是 C# 唯一可靠的高精度计时器

.NET 中只有 Stopwatch 能真正利用硬件 HPET(High Precision Event Timer)或 TSC(Time Stamp Counter),其他如 Timer 类(System.Threading.TimerSystem.Windows.Forms.Timer)都基于系统消息循环或线程池调度,分辨率通常在 10–15 ms,且受 GC、线程抢占影响极大。

使用 Stopwatch 的关键点:

var sw = Stopwatch.StartNew();
// 执行待测操作
DoWork();
sw.Stop();
Console.WriteLine($"耗时: {sw.ElapsedTicks} ticks ({sw.Elapsed.TotalMilliseconds:F3} ms)");

模拟“中断响应”的常见替代方案

多数场景下,所谓“硬件中断处理”可降级为快速轮询 + 事件驱动组合:

注意:DataReceived 等事件不是实时的——从硬件引脚电平变化到 C# 事件触发,中间经过中断 → ISR → DPC → I/O 完成例程 → 消息泵 → 托管委托调用,典型延迟在几百微秒到几毫秒不等。

硬实时需求必须绕过 .NET

如果任务要求确定性响应(如运动控制中 ≤ 50 μs 抖动),C# 不适合直接承担中断服务逻辑。可行路径只有:

哪怕只是读取一个 PCIe 设备的寄存器,只要要求亚毫秒级确定性,C# 就不该出现在中断上下文里——这是运行时模型决定的硬边界。