【问题标题】:How to prevent a C# System.Timers timer event from blocking subsequent events?如何防止 C# System.Timers 计时器事件阻塞后续事件?
【发布时间】:2014-09-23 19:41:33
【问题描述】:

我有一个 C# 应用程序,它使用 System.Timers 计时器重复调用一个函数。问题是,根据工作负载,如果函数调用的处理达到一定的 CPU 使用率 (98-100%),任何后续事件都会被阻止。

有没有办法防止这种情况发生,使事件不被阻塞?

例如,计时器的事件处理程序是一个执行动态代码的函数,它可能需要一些时间和资源来处理。在此类处理期间,布尔值设置为 true,这会导致任何后续事件调用写入日志文件。但是,一旦事件的处理达到高 CPU 使用率,其他事件将不会写入日志文件。

【问题讨论】:

  • 工作负载是否完全放在 UI 线程上?为长时间运行的进程提供自己的线程,或使用async 调用它们,以便它们排到最后。
  • 定时器的事件处理函数是一个执行动态代码的函数,可能需要一些时间和资源来处理。在此类处理期间,布尔值设置为 true,这会导致任何后续事件调用写入日志文件。但是,一旦事件的处理达到高 CPU 使用率,其他事件将不会写入日志文件。
  • 请注意,您问的是“如何使用 110% 的 CPU 资源”,这有点困难……您可能需要重新考虑在没有可用资源时能够运行代码的要求。跨度>
  • System.Timers.Timer 是一个 evil 类。它只有在阳光明媚并且背风吹拂时才能正常工作。当机器负载过重时,它尤其会失败,而且总是以无法诊断的方式进行。您需要通过始终编写 try/catch 来防止异常被吞下,从而消除其最糟糕的行为。并且通过将其 AutoReset 属性设置为 false,如果 Interval 太低,这是一个非常危险的属性。它导致的重入根本无法用 bool 解决,只有使用 lock 的真正多重排除才能完成这项工作。
  • 我认为你应该改变你的方法。很明显,您的系统可以在事件驱动模型中完成更多工作。将需要处理的项目添加到队列对象。使用当前计时器排队工作。然后您应该将处理逻辑更改为 [线程池][1] 计时器还应该管理线程池。 [1]:msdn.microsoft.com/en-us/library/…

标签: c# events timer system.timers.timer


【解决方案1】:

是的,将 Timers 属性 AutoReset 设置为 true。

阅读:https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx

【讨论】:

    猜你喜欢
    • 2013-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多