当计算机的资源利用率较高时,.NET 计时器不会回调

本文关键字:计时器 NET 回调 高时 计算机 资源 利用率 | 更新日期: 2023-09-27 18:36:36

我每隔几秒钟就使用 System.Timers.Timer 进行回调。回调基本上是将连续的心跳消息发送到连接的服务器。

如果检测信号消息在 n 秒内未发送,则服务器会将其与连接的客户端断开连接。

我观察到,当用户机器的资源利用率非常高时,例如 - 100% 的 CPU 利用率和几乎 95% 的内存利用率和系统没有响应用户交互,那么不会调用计时器回调。

我也尝试了System.Threading.Timer但没有运气,得到了相同的结果。

在 .NET 中确保无论计算机资源利用率如何都调用操作的最佳方法是什么。

注意

  • 此实现在正常情况下非常完美。
  • 我没有使用我的 Windows 应用程序中的 UI 线程来调用回调,而是使用后台(非 UI)线程。

当计算机的资源利用率较高时,.NET 计时器不会回调

看起来您的周期性检测信号对您的应用程序非常关键,甚至可能比 UI 响应能力和其他问题更重要。
在这种情况下,在实时系统中,通常会为具有高优先级的线程创建一个专用线程。
因此,尝试创建一个专用线程(不是 BackgroundWorker 而是新的 System.Threading.Thread),赋予它高优先级 (ThreadPriority.Highest) 并从此优先级线程发送检测信号。

"在 .NET 中确保你的操作调用而不考虑计算机资源利用率的最佳方法是什么"的答案取决于你对"不尊重"的定义。

这个问题属于实时计算领域。

如果您努力在 Windows 上使用 C#,恐怕您最接近您的目标就是将 Thread 置于"实时"优先级,然后在调用之间使用 SpinWait。结果将是您的线程将占用单个内核的 100% 利用率。

即便如此,您也可能遇到时间问题。

您可能想看看如何在C++中使用实时操作系统和程序。

但是,这两种解决方案都非常昂贵。

但是,我建议您解决问题的真正核心,即您的应用程序显然使用线程效率低下。您可能希望使用异步 I/O 重写整个应用程序,这应该会降低 CPU 利用率。

还可以尝试水平横向扩展应用程序。但很明显,您的系统已经超出了盒子。

我选择的最后一个方法是 -

  • 将 ping 频率(检测信号)持续时间从现有的 n 秒提高到 3 * n 秒。
  • 从高优先级线程发送 ping 消息。

我不得不承认,这仍然不能解决问题,而只是试图延迟失败。