3

I have a C# application that uses a System.Timers timer that repeatedly calls a function. The problem is, depending on the workload, if the processing from a function call reaches a certain CPU usage percentage (98-100%), any subsequent events are blocked.

Is there a way to prevent such a scenario so that events are not blocked?

For example, the timer's event handler is a function that executes dynamic code, which may take some time and resources to process. During such processing a boolean is set to true which causes any subsequent event calls to write to a log file. Once an event's processing has reached a high CPU usage though, additional events will not write to the log file.

reformed
  • 4,505
  • 11
  • 62
  • 88
  • 3
    Is the workload being placed entirely on the UI thread? Give long-running processes their own threads, or call them with `async` so that they go to the back of the line. – Robert Harvey Jul 31 '14 at 18:13
  • What do you meant by blocked? Are you referring delayed? – Sriram Sakthivel Jul 31 '14 at 18:13
  • Blocked as in, the function is not called. CPU % at these instances is ~100%. – reformed Jul 31 '14 at 18:15
  • You mean never called again? or called after cpu usage comes down? – Sriram Sakthivel Jul 31 '14 at 18:16
  • Once the CPU frees up, they are called again. But during that period, all other events are not called. – reformed Jul 31 '14 at 18:16
  • Is this specific to events? Im pretty sure this has to do with thread scheduling in general when load is very high – Yuval Itzchakov Jul 31 '14 at 18:17
  • 1
    The timer's event handler is a function that executes dynamic code, which may take some time and resources to process. During such processing a boolean is set to true which causes any subsequent event calls to write to a log file. Once an event's processing has reached a high CPU usage though, additional events will not write to the log file. – reformed Jul 31 '14 at 18:21
  • 1
    Note that you are asking "how to use 110% of CPU resources" which is somewhat hard... You may need to reconsider your requirement to be able to run code when no resources available. – Alexei Levenkov Jul 31 '14 at 18:24
  • I'm not asking to use 110% CPU. I'm asking how to prevent one event from blocking other events, even if that means restricting one event to, say, 50% CPU. – reformed Jul 31 '14 at 18:25
  • @reformed what about Robert Harvey's comment? – fabricio Jul 31 '14 at 18:43
  • 1
    System.Timers.Timer is an *evil* class. It only works properly when the sun is shining and you've got the wind in your back. It particularly fails when the machine gets heavily loaded, invariably in an impossible to diagnose way. You need to take the sting out its worst behavior by always writing a try/catch to prevent exceptions from getting swallowed. And by setting its AutoReset property to *false*, an extraordinarily dangerous property if the Interval is too low. The re-entrancy it causes simply can't be solved with a *bool*, only true multiple exclusion with *lock* can do that job. – Hans Passant Jul 31 '14 at 19:45
  • 2
    I think you should change your methodology. It is clear that you have more work that your system can do in a event driven model. Add items that need processing to a queue object. Use the current timer to en queue work. Then you should change your processing logic to a [thread pool][1] The timer should also manage the thread pool. [1]: http://msdn.microsoft.com/en-us/library/0ka9477y(v=vs.110).aspx#TaskParallelLibrary – Threekill Sep 09 '14 at 14:50

1 Answers1

0

Yes, set the Timers property AutoReset to true.

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

Martin Mulder
  • 12,642
  • 3
  • 25
  • 54