What happens with timer tick after wake up from stand-by? - c#

My C#-programm has a windows.forms.timer that fires all 24h for a background task.
During a day I put my Vista 64bit several times in stand-by mode (never switch it off).
It seems that after wake-up the timer is sort of reset.

Your timer shouldn't be set to fire every 24 hours, it should be set to fire every few seconds, or minutes, and check the time. If the time is greater than, or equal to, the time you want your task to occur, perform the task.

The Timer class is very relaxed about raising its Tick event. Internally, inside the Windows code, when the timer is due it only sets an internal flag, somewhat akin to "ought to deliver WM_TIMER". That doesn't actually happen until nothing important needs to be done by the message loop. Any message gets higher priority than WM_TIMER.
When the Windows Forms message loop calls GetMessage(), the function checks if anything needs to be returned. If the answer is "nothing" and the flag is set, it supplies WM_TIMER. And you'll get the Tick event.
A couple of consequences from that: you can never use the Tick event to keep track of time. That will inevitably fall behind. You can never get the Tick event twice in a row, it doesn't catch up. But relevant to your question: the message loop isn't pumping when the machine goes in stand-by, nothing special happens.

During standby, typically memory is stored as-is, then recalled when you wake the machine, which might cause your timer to either not tick during the stand-by, or have imprecise behavior from what you intend.

Related

Timer Interval Increases when CPU utilization and memory increases

I have a Timer in my code for some 'x' seconds. The code has multiple threads and there are multiple timers. Now I notice that, my application goes to a hang state after running for some time and from the logs I notice that the timer interval varies. It has increased. How is this possible and can anyone provide a solution for this? Is there any alternative for timer in c#
_timernew = new System.Timers.Timer(10000)
{
AutoReset = false
};
_timernew .Elapsed += (sender, e) => { DoSomething };
_timernew .Enabled = true;
Timers are not precise. The interval is the minimum delay before the event is fired, but you are not guaranteed your timer event will get executed exactly when the interval elapses.
When the interval elapses, the timer queues your even handler to the thread pool. Therefore, the event handler will get executed when there is an available thread in the threadpool to take the handler, and then an available CPU core to actually execute it.
In other words, the more busy the computer is, the more likely delays will happen.
If you need a closer to real-time execution, you must use a dedicated thread and set its priority to high:
Thread myThread = new Thread(MyThreadMethod);
myThread.Priority = ThreadPriority.Highest;
myThread.Start();
Now, however, in your MyThreadMethod, you need to implement a sophisticated mechanism that monitors how much time has elapsed and decide whether you must execute your actual code or not.
You should not just loop and check the time, because that will occupy a single core at 100%. Perhaps you can use the dreaded Thread.Sleep with a smaller interval and check if time has passed. You must use a smaller interval than the one you need at a magnitude of at least 10. Thread.Sleep is not precise, too.

Xamarin C# cross-platform timeout timer

I need a very standard thing, a timeout timer, but it's for a PCL (Portable Class Library) Xamarin app, and there's a lot of functionality missing there. The interface I need looks something like this:
class Timeout
{
// The 'OnTimeout' event is triggered when at least numSeconds have elapsed
public delegate void VoidFunc();
public event VoidFunc OnTimeout;
// Construct the Timeout object and start the timer.
public Timeout(int numSeconds);
// Restart the timer.
public void Restart();
}
So if I construct the Timeout object at 12:00:00 as Timeout(30), then call Restart() at 12:00:29, the event fires exactly once, at 12:00:59.
Unfortunately, Xamarin cross-platform doesn't have a Timer class, so I can imagine two possibilities:
1) Construct a timer using Xamarin.Forms.Device.StartTimer when the Timeout object is constructed, and have it keep firing every second (or every quarter second or something). Every time it fires, it checks if it's supposed to trigger the event or not.
2) Start up a thread in the Timeout() constructor, have it sleep most of the time but wake up every second (or quarter second) and check if it's time to fire the event.
Neither of these options seems great to me -
1) Xamarin.Forms.Device.StartTimer works with the UI thread, so it's potentially less accurate (if the UI is busy, the event won't fire).
2) System overhead of constructing a thread, and coding overhead of making sure the thread shuts down pleasantly if the Timeout() object is destructed before the event is fired.
Both options end up wasting a tiny bit of CPU every time they wake up and realize it's not time to fire the event, certainly not a huge deal but the kind of thing I usually try to avoid doing.
Is there a more elegant solution that I'm missing?

AddTimeout or AddIdle for UI updates on GTK main thread?

When making UI updates with GTK# (GDK2), such as changing label text, setting button visibility etc, should I as a general rule be using Gdk.Threads.AddTimeout or Gdk.Threads.AddIdle?
The GDK2 documentation states that AddIdle
Adds a function to be called whenever there are no higher priority events pending.
So it would seem that AddTimeout would provide a more responsive update. However the documentation states:
Note that timeout functions may be delayed, due to the processing of
other event sources. Thus they should not be relied on for precise
timing.
Which leads me to believe Idle and Timeout are both about as responsive as each other (which they seem to be, when running code).
A comment in some code I am working on suggests that Timeout results in a faster update but hits the UI harder, but I cannot find any sources to back this up.
So as a general rule, which of these methods should I be using to perform GTK updates in the main thread?
Threads.AddTimeout(0, 0, () =>
{
// do something;
return false;
});
vs
Threads.AddIdle(0, () =>
{
// do something;
return false;
});
The timeout callback is appropriate if you need something to happen after a specific period of time. An example of this would be blinking a cursor in a text field (not that you should implement that yourself).
Idle timeout gets called the once the main loop finishes executing everything else that is ready. The difference if you are just calling it once is priority. If you have some other event being handled by the main loop doing it in the idle handler guarantees that the other thing happens first.
The difference becomes more readily apparent when you return true, and get a repeated callback. If you do this in an idle callback you end up using as much CPU as the OS will let you, but your UI remains responsive assuming each callback is fast. If you do this with a timeout you get much more predictable behavior.
The only reason I would think this hits the UI harder is that it defaults to a higher priority, and could potentially delay draw events. Priority DEFAULT_IDLE < HIGH_IDLE (draw) < DEFAULT.

When is the GUI overloaded?

Suppose you are permanently invoking a method asynchronously onto the UI thread/dispatcher with
while (true) {
uiDispatcher.BeginInvoke(new Action<int, T>(insert_), DispatcherPriority.Normal, new object[] { });
}
On every run of the program you observe that the GUI of the application begins to freeze after about 90 seconds due to the flood of invocations (time varies but lies roughly between 1 and 2 minutes).
How could one exactly determine (measure ?) the point when this overloading occurs in order to stop it early enough ?
Appendix I:
In my actual program I don't have an infinite loop. I have an algorithm that iterates several hundred times before terminating. In every iteration I am adding a string to a List control in my WPF application. I used the while (true) { ... } construct because it matches best what happens. In fact the algorithm terminates correctly and all (hundreds) strings are added correctly to my List but after some time I am loosing the ability to use my GUI until the algorithm terminates - then the GUI is responsive again.
Appendix II:
The purpose of my program is to observe a particular algorithm while it's running. The strings I am adding are log entries: one log string per iteration. The reason why I am invoking these add-operations is that the algorithm is running in another thread than the UI thread. To catch up with the fact that I can't do UI manipulation from any thread other than the UI thread I built some kind of ThreadSafeObservableCollection (But I am pretty sure that this code is not worth posting because it would detract from the actual problem what I think is that the UI can't handle the repeatedly and fast invocation of methods.
It's pretty straight forward: you are doing it wrong by the time you overload the user's eyeballs. Which happens pretty quickly as far as modern cpu cores are concerned, beyond 20 updates per second the displayed information just starts to look like a blur. Something the cinema takes advantage of, movies play back at 24 frames per second.
Updating any faster than that is just a waste of resources. You still have an enormous amount of breathing room left before the UI thread starts to buckle. It depends on the amount of work you ask it to do, but typical is a x50 safety margin. A simple timer based on Environment.TickCount will get the job done, fire an update when the difference is >= 45 msec.
Posting that often to the UI is a red flag. Here is an alternative: Put new strings into a ConcurrentQueue and have a timer pull them out every 100ms.
Very simple and easy to implement, and the result is perfect.
I've not used WPF--just Windows Forms, but I would suggest that if there is a view-only control which will need to be updated asynchronously, the proper way to do it is to write the control so that its properties can be accessed freely from any thread, and updating a control will BeginInvoke the refresh routine only if there isn't already an update pending; the latter determination can be made with an Int32 "flag" and Interlock.Exchange (the property setter calls Interlocked.Exchange on the flag after changing the underlying field; if the flag had been clear, it does a BeginInvoke on the refresh routine; the refresh routine then clears the flag and performs the refresh). In some cases, the pattern may be further enhanced by having the control's refresh routine check how much time has elapsed since the last time it ran and, if the answer is less than 20ms or so, use a timer to trigger a refresh 20ms after the previous one.
Even though .net can handle having many BeginInvoke actions posted on the UI thread, it's often pointless to have more than update for a single control pending at a time. Limit the pending actions to one (or at most a small number) per control, and there will be no danger of the queue overflowing.
ok, sorry for the bad link before in the comments, but I kept reading and maybe this will be of help:
The DispatcherOperation object returned by BeginInvoke can be used in several ways to interact with the specified delegate, such as:
Changing the DispatcherPriority of the delegate as it is pending execution in the event queue.
Removing the delegate from the event queue.
Waiting for the delegate to return.
Obtaining the value that the delegate returns after it is executed.
If multiple BeginInvoke calls are made at the same DispatcherPriority, they will be executed in the order the calls were made.
If BeginInvoke is called on a Dispatcher which has shut down, the status property of the returned DispatcherOperation is set to Aborted.
Maybe you can do something with the number of delegates that you are waiting on...
To put supercat's solution in a more WPF like way, try for an MVVM pattern and then you can have a separate view model class which you can share between threads, perhaps take locks out at apropriate points or use the concurrent collections class. You implement an interface (I think it's INotifyPropertyChanged and fire an event to say the collection has changed. This event must be fired from the UI thread, but only needs
After going through the answers provided by others and your comments on them, your actual intent seems to be ensuring that UI remains responsive. For this I think you have already received good proposals.
But still, to answer your question (how to detect and flag overloading of UI thread) verbatim, I can suggest the following:
First determine what should be the definition of 'overloading' (for e.g. I can assume it to be 'UI thread stops rendering the controls and stops processing user input' for a big enough duration)
Define this duration (for e.g. if UI thread continues to process render and input messages in at-most 40ms I will say it is not overloaded).
Now Initiate a DispactherTimer with DispatcherPriority set according to your definition for overloading (for my e.g. it can be DispatcherPriority.Input or lower) and Interval sufficiently less than your 'duration' for overloading
Maintain a shared variable of type DateTime and on each tick of the timer change its value to DateTime.Now.
In the delegate you pass to BeginInvoke, you can compute a difference between current time and the last time Tick was fired. If it exceeds your 'measure' of overloading then well the UI thread is 'Overloaded' according to your definition. You can then set a shared flag which can be checked from inside your loop to take appropriate action.
Though I admit, it is not fool proof, but by empirically adjusting your 'measure' you should be able to detect overloading before it impacts you.
Use a StopWatch to measure minimum, maximum, average, first and last update durations. (You can ouput this to your UI.)
Your update frequency must be < than 1/(the average update duration).
Change your algorithm's implementation so that it iterations are invoked by a multimedia timer e.g. this .NET wrapper or this .NET wrapper. When the timer is activated, use Interlocked to prevent running a new iteration before current iteration is complete. If you need to iterations on the main, use a dispatcher. You can run more than 1 iteration per timer event, use a parameter for this and together with time measurements determine how many interations to run per timer event and how often you want the timer events.
I do not recommend using less than 5mSec for the timer, as the timer events will suffocate the CPU.
As I wrote ealier in my comment, use DispatcherPriority.Input when dispatching to the main thread, that way the UI's CPU time isn't suffocated by the dispatches. This is the same priority the UI messages have, so that way they are not ignored.

C#: What if System.Windows.Forms.Timer interval was not enough for doing a job?

First, sorry for my bad english writing.
Suppose that we have a win form (C#) that has a timer. The timer interval has been set to 60000 milsec. So its tick event will be fired every 1 milute. Suppose we have written a method that handles tick event called Timer1_Tick. What if the job needs more that 1 minute to complete?
You've got several options, here's four I can think of:
Abandon the current job to start the new one. The big downside of this one is, of course, if the current job can't be stopped.
Wait for the current job to finish before starting the new one. This might leave you with a queue of pending jobs if each one takes more than a minute.
Don't start the new job. Let the current one finish and then wait for the next timer interval to start the new job.
Increase the interval between jobs. This is just putting off the problem.
There is no right answer. You'll have to work out what's best and works for your situation.
I'd go for #3 as my first solution.
Setup a flag that will allow you to check if the long running job has finished and only run the job if it has finished. Don't forget to reset the flag after finishing the long running job:
// field
private bool finishedWork = true;
public void Timer1_Tick(Object o, EventArgs e)
{
if (finishedWork)
{
finishedWork = false;
// do work
finishedWork = true;
}
}
Another option is to simply disable the timer between operations:
public void Timer1_Tick(Object o, EventArgs e)
{
if (finishedWork)
{
Timer1.Enabled = false;
// do work
Timer1.Enabled= true;
}
}
So set a flag when you start the job and check the flag when the timer fires. If the flag is set, do nothing in the timer handler. Remember to clear the flag when the job completes.
Are you spinning off a worker thread to do the job?
Another timer event will likely be queued, causing Timer1_Tick to be called again almost immediately after it returns. (IIRC, though, timer ticks are one of the lowest priority messages, so it'll probably handle any other messages it's had queued up to that point first, except maybe paint messages).
Note, if your function takes longer than 2 minutes to run, it's possible (read: likely) that only the latest tick will be in the queue.
If your tick processing takes longer than the timer interval, you should look into raising the interval. Either way, you should probably be doing the work in a background thread and making sure you don't start another thread if the last tick's task isn't done. Otherwise you could end up with hordes of threads all slowing each other down til your program collapses under its own weight.
Store the current state of the process in a field or property and start the process only if the state is no "running".
Disable the timer at the start of Timer1_Tick and then enable it again afterwards?
There are multiple types of Timers in .Net: One is in a System.Timers namespace, another is in System.Windows.Forms namespace and another in System.Threading.
The System.Windows.Forms.Timer control is based on UI thread and message loops, meaning it will queue the timer events and if your handler exceeds the interval, it will be called immediately after ending.
The other two timers are based on threading, and are very accurate. They will reenter you handler after the time elapsed.

Categories