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

C# 当计算机资源利用率较高时,.NET计时器不会回调,c#,timer,C#,Timer,我正在使用System.Timers.Timer进行每隔几秒钟的回调。 回调基本上向连接的服务器发送连续的心跳消息 若心跳消息在n秒内未发送,则服务器会将其从连接的客户端断开连接 我观察到,当用户机器的资源利用率非常高时,比如-100%的CPU利用率和近95%的内存利用率,并且系统没有响应用户交互,那么定时器回调就不会被调用 我还尝试了System.Threading.Timer,但没有成功,得到了相同的结果 在.NET中,无论机器资源利用率如何,确保您的操作调用的最佳方法是什么 注意 这种实

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

若心跳消息在n秒内未发送,则服务器会将其从连接的客户端断开连接

我观察到,当用户机器的资源利用率非常高时,比如-100%的CPU利用率和近95%的内存利用率,并且系统没有响应用户交互,那么定时器回调就不会被调用

我还尝试了
System.Threading.Timer
,但没有成功,得到了相同的结果

在.NET中,无论机器资源利用率如何,确保您的操作调用的最佳方法是什么

注意

  • 这种实现在正常情况下工作得非常好
  • 我没有使用windows应用程序中的UI线程来调用回调,而是使用后台(非UI)线程

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

回答“在.NET中,无论机器资源利用率如何,确保操作调用的最佳方法是什么。”取决于您对“不考虑”的定义

这个问题存在于实时计算领域

如果你试图在windows上使用C#,恐怕最接近你的目标是将线程设置为“实时”优先级,然后在调用之间使用SpinWait。其结果是,您的线程将占据单个核心的100%利用率

即使这样,你也可能会遇到时间问题

您可能想看看使用C++中的实时操作系统和程序。 然而,这两种解决方案都非常昂贵

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


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

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

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

我必须承认,这仍然不能解决问题,只是试图延迟故障。

当机器的CPU利用率达到100%时,没有更多的CPU可用于运行计时器任务。所有的应用程序都在争夺处理器时间,而在你的应用程序中,计时器触发的动作正在与所有其他东西(UI线程和其他后台线程)争夺。计时器线程在这里可能不是赢家,这很正常。@MarcinJuraszek我有另一个小Java小程序,它仍然受到CPU的关注,并将心跳发送到服务器,我想知道.NET应用程序为什么不呢?如果我使用本机代码(C++),会有帮助吗?可能是
计时器
的优先级很低。我认为没有办法设置它。你能使用Windows窗体计时器吗?它在UI线程上执行,可能会获得更高的优先级。如果机器严重过载,导致页面文件被破坏,并且用户输入不再响应,那么获得及时事件处理程序的几率也会迅速下降。服务器得出了正确的结论,机器实际上已经无法提供足够的服务保证。您必须限制其工作负载或购买更多RAM。这减少了它无法发送心跳信号的次数。