I am using a timer with interval 1 second.
But in the timer's tick event when I print the time it's always 62 or 65 ms.
I don't understand why it's taking 10 ms more.
Please can some one have look into this.
Here is the code I am using:
static int _counter;
var _timer = new System.Timers.Timer(1000);
public Form1()
{
InitializeComponent();
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine(DateTime.Now.ToString("{hh:mm:ss.fff}"));
_counter++;
if (_counter == 20)
_timer.Stop();
}
And this the output:
{01:59:08.381}
{01:59:09.393}
{01:59:10.407}
{01:59:11.421}
{01:59:12.435}
{01:59:13.449}
{01:59:14.463}
{01:59:15.477}
{01:59:16.491}
{01:59:17.505}
{01:59:18.519}
{01:59:19.533}
{01:59:20.547}
{01:59:21.561}
{01:59:22.575}
{01:59:23.589}
{01:59:24.603}
{01:59:25.615}
{01:59:26.629}
{01:59:27.643}
You need to understand that Windows is not a real-time operating system. Real-time operating systems have timer mechanisms that allow the system to make hard guarantees about when timer-initiated events occur and the overhead associated with them, and allow you to specify what behavior should occur when the deadline is missed -- for example if the previous execution took longer than the interval.
I would characterize the Windows timers as "best effort" when it comes to smaller intervals. When the interval is sufficiently long you don't notice that you aren't getting the exact interval that you requested. As you get closer and closer to the resolution of the timer (the frequency at which the timer runs), you start seeing the overhead as a percentage of the interval increase. Real-time systems take special care to minimize the software overhead, relying on more sophisticated and faster hardware solutions. The exact frequency of the Windows timer depends on the timing services that the underlying hardware provides and so may differ from system to system.
If you have real-time needs -- and doing something every 50ms may fall into that category -- then you may need to look at specialized hardware and/or a real-time OS.
It's because of the limited resolution of the system clock. The event occurs at the next system tick after the specififed time, so you will always get a few extra milliseconds.
If you need a more precise timer, you can hook into the Win32 Multimedia Timer, it is the most accurate timer (down to 1ms). Here's an article on CodeProject showing how to hook into it from C#.
First, as other people have noted, you're setting it to 1s, not 50ms.
Secondly, windows is not a real-time OS. None of the timer classes are exactly precise. All you're doing it saying that you want to wait at least this long. It takes some amount of time for everything to fire and you to end up notified that the timer has ticked once windows gets around to actually servicing the tick message.
Note that usually, in most language, sleep calls specify the minimum time after which a process would awaken. After the specified time has passed, the process is put on a queue and hopefully the scheduler activates it. But this activation may sometimes be delayed. I'm not sure about the Timer class, but I suspect it may suffer from a similar problem.
You may perhaps try to increase the priority of your process to cut down the increased time.
System.Timers.Timer is not a precise timer. Especially when system is under load it can have even bigger delays.
Also to get better accuracy in your example change time measuring code to use Stopwatch class.
static int _counter;
System.Timers.Timer _timer = new System.Timers.Timer(1000);
Stopwatch sw;
public Form1()
{
InitializeComponent();
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
sw = Stopwatch.StartNew();
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine(sw.ElapsedMilliseconds);
_counter++;
if (_counter == 20)
_timer.Stop();
sw.Reset();
sw.Start();
}
Using the system timers will always be a little longer than the value requested. This is due to the overhead of the other processes in the system.
On my system it's 14ms. Having googled; the difference is down to context thread switching delay. There's an article regarding high resolution timers here
As other responders have mentioned, Windows is not a real-time OS. If you must use windows, try using Win CE or Windows Embedded.
-S!
The accuracy of the time may depend on how many processes run. If you have that option , I would reduce the number of processes that run on your computer one by one and I mean those which consume significant cpu time,I would check if the times improve. Especially, browsers, virus scanners,programs running in the background.
The deviations are normal since they are not RTOS (real time operating systems). This is the best solution that I've found under the circumstances: Link
Program.MicroTimer microTimer = new Program.MicroTimer();
microTimer.MicroTimerElapsed += new Program.MicroTimer.MicroTimerElapsedEventHandler(OnTimedEvent);
microTimer.Interval = 1000; // Call micro timer every 1000µs (1ms)
// Can choose to ignore event if late by Xµs (by default will try to catch up)
// microTimer.IgnoreEventIfLateBy = 500; // 500µs (0.5ms)
microTimer.Enabled = true; // Start timer
System.Threading.Thread.Sleep(2000);
microTimer.Enabled = false;
Those are the code snippets. You can try them to see the values in the console.
Related
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.
To Show a timer for how Long a specific process runs I'm using a Background worker to update an execution time Label. Naturally this should be done every second so that the user sees that it increases consistently.
After trying around a bit and failing utterly I went down the road that I'm checking every 150 milliseconds if the next second is already there and then I update the Display.
private void ExecutionTimerBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
Stopwatch executionTime = new Stopwatch();
double lastUpdateAtSeconds = 0;
executionTime.Start();
while (!ExecutionTimerBackgroundWorker.CancellationPending)
{
Thread.Sleep(150); // Sleep for some while to give other threads time to do their stuff
if (executionTime.Elapsed.TotalSeconds > lastUpdateAtSeconds + 1) // Update the Execution time display only once per second
{
ExecutionTimerBackgroundWorker.ReportProgress(0, executionTime.Elapsed); // Update the Execution time Display
lastUpdateAtSeconds = executionTime.Elapsed.TotalSeconds;
}
}
executionTime.Stop();
}
private void ExecutionTimerBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Update the display to the execution time in Minutes:Seconds format
ExecutionTimeLabel.Text = ((TimeSpan) e.UserState).ToString(#"mm\:ss");
}
Now this seems to me a bit inefficient as I run it every 150 milliseconds to just look "hey has the next second already arrived or not". I also tried a different Approach already where I calculate how much time is needed until the next second but at that one I had a few instances where a jump by 2 instead of 1 second each in the Display happened.
So my question here is: Is there any more efficient way to do this? Or is that already how it should be done?
I have found that if you want to display changes every second then you should attempt to make the changes every tenth of a second for it to appear continuous for the user - maybe even more often than that.
Now I would avoid the use of a background worker entirely for this. Instead I'd use Microsoft's Reactive Framework (NuGet "Rx-Main" or "Rx-WinForms" in your case).
Here's the basic code for that:
var start = DateTimeOffset.Now;
var subscription =
Observable
.Interval(TimeSpan.FromSeconds(0.1))
.Select(x => DateTimeOffset.Now.Subtract(start).TotalSeconds)
.Select(x => (int)x)
.DistinctUntilChanged()
.ObserveOn(this)
.Subscribe(x => this.label1.Text = x.ToString());
This code creates a timer (.Interval(...)) that fires every tenth of a second. It then computes the time in seconds since the code started, turns this into an integer, and drops all consecutive values that are the same. Finally it observes the observable on the UI thread (.ObserveOn(this)) and then subscribes by assigning the value to (in my case) a label on my form - you could use whatever control type you liked.
To stop the subscription, just do this:
subscription.Dispose();
It will clean up everything properly.
The code should be quite readable event if you are not familiar with the Reactive Framework.
Now I've used DateTimeOffset instead of Stopwatch as you don't need high resolution timing for updates occurring every second. Nothing would stop you using a Stopwatch if you wanted.
For that matter I would suggest using System.Windows.Forms.Timer. With this timer you will not run into cross-thread issues when updating Label text and it is very easy to use.
private Timer timer;
private int secondsElapsed;
private void InitTimer()
{
timer = new Timer();
timer.Interval = 1000; // milliseconds
timer.Tick += new EventHandler(timer_Tick);
}
void timer_Tick(object sender, EventArgs e)
{
secondsElapsed++;
lblSecondsElapsed.Text = secondsElapsed.ToString();
}
private void btnStart_Click(object sender, EventArgs e)
{
secondsElapsed = 0;
timer.Start();
}
private void btnAbort_Click(object sender, EventArgs e)
{
timer.Stop();
}
Edit:
Source: MSDN - Timer Class (System.Windows.Forms)
This timer is optimized for use in Windows Forms applications and must be used in a window.
Note
The Windows Forms Timer component is single-threaded, and is limited to an accuracy of 55 milliseconds. If you require a multithreaded timer with greater accuracy, use the Timer class in the System.Timers namespace.
You might want to take a look at System.Threading.Timer or System.Timers.Timer, but to be honest, even if you set the interval to 1 second, both are not very precise :/ most of the time, i go with 990ms or i use a thread much like you use your BackgroundWorker (and i don't think those timers really work any different).
Edit: Funny enough, i just looked in the .NET Framework and the Timers.Timer internally uses the Threading.Timer.
You are totally right in your findings regarding the needed sampling interval for fluent changes of the displayed second. A human observer does know when the next second is due to arrive and hence notices even slight skews between this and the moment it actually is displayed. Thus you really need to make your check well below the sub-second level.
All considerations around efficiency should be centered around the question wether your check is computationally expensive or not. In your example above, the time spent in the if-clause is negligible, so the thread is quickly going to sleep again anyway. Thus you could safely afford small sleeping intervals 'just' to make display fluent.
If, however, your check would be computationally expensive, you could opt for adaptive sleeping: Sleep long if next second is far away, short when it is due soon...
Please be arware of the fact that, as Anton Kedrov stated, updating GUI components from any other than the GUI thread does throw an exeption. Depending on the grade of artificiality of your example, you should either opt for a completely timer-based solution, or insert a decoupling System.Windows.Forms.Timer to shovel the calculated values (via thread safe fields, please) to the GUI.
What .NET object (or technique) is the most precise at launching a thread every XXX milliseconds? What are the tradeoffs?
For example:
int maxDurationMs = 1000;
while (true)
{
DateTime dt = DateTime.UtcNow;
DoQuickStuff()
TimeSpan duration1 = DateTime.UtcNow - dt;
int sleepTime = maxDurationMs - duration1.Milliseconds;
if (sleepTime > 0)
System.Threading.Thread.Sleep(sleepTime);
}
or
// CPU Intensive, but fairly accurate
int maxDurationMs = 1000;
while (true)
{
DateTime dt = DateTime.UtcNow;
DoQuickStuff()
while (true)
{
if (dt.AddMilliseconds(maxDurationMs) >= DateTime.UtcNow)
break;
}
}
Alternate methods of doing the same thing, but with varying degrees of accuracy and tradeoffs (CPU, etc)
System.Timer
DispatchTimer
System.Threading.Timer
Thread.Join
.NET 4.0 Task
Thread.Sleep()
Monitor.Wait(obj, timespan)
Multimedia Timers (thanks Brian Gideon)
Win32 High Resolution timers
Something else?
I have never actually used them myself, but Multimedia Timers are said to have the best resolution of any timer service in Windows. The .NET BCL does not have a wrapper for this timer service yet so you will have to do the P/Invoke calls yourself.
Another option might be to use Stopwatch together with some standard Thread.Sleep calls in a tight loop. I am not sure how much luck you would have with this approach, but it might be more accurate than a plain old Thread.Sleep call by itself. I have never tried it, but anything is worth a shot I suppose.
I did some experiments and I discovered that changing the thread priority to ThreadPriority.Highest made a considerable difference. It reduced the standard deviation of the interval by quite a bit on each technique I tried.
Don't use DateTime: its accuracy is limited to around 16ms on most systems. (See Eric Lippert's blog)
The most accurate method would be to have a dedicated thread running a while loop with a System.Diagnostics.Stopwatch object to count the time.
Even with the most precise and accurate timer in existance, raising an event exactly every x milliseconds is no simple task given the unpredictability of CPU time slices: I suggest looking into how games do their main loop (achieving a stable 30fps with lag compensation, for instance). A good example is OpenTK's GameWindow, specifically the RaiseUpdateFrame method.
If you want precise intervals Windows Timers are probably not what you need to be using, probably some sort of RTOS would be better suited for you.
From above link:
The Timer API was created to address problems with currently available timers... However, Windows timers are not as accurate as applications may require. Although Windows timer messages can be scheduled with millisecond accuracy, they seldom deliver that result because the accuracy of a Windows timer is dependent on the system clock and current activity. Because WM_TIMER messages are processed at a low priority, somewhat like WM_PAINT messages, they are often delayed while other messages are processed.
In my window services periodic actions i use Monitor.Wait because it releases a Thread and allows me to perform action without worrying about next "timer tick" before i finish.
With this I get +/- 1 ms precision. If everything goes right.
But if You need perfect precision that you can count on You shouldn't use .NET. Actually You shouldn't use Windows. There always is a possibility that Your process (or thread) will be postponed in execution.
The basic implementation of System.Timers.Timer object skewed approx 120 MS and caused me to skip at least one second every minute.
I am able to use the following technique to get a timer accurate within 1ms on a 1 minute interval. Shorter intervals may not be able to achieve the same accuracy (plus the overhead to DoWork() plays a part in this efficiency)
public class SystemTimerTest
{
readonly System.Timers.Timer timerRecalcStatistics;
readonly System.Diagnostics.Stopwatch stopwatchForRecalcStatistics = new System.Diagnostics.Stopwatch();
public SystemTimerTest(TimeSpan range, DataOverwriteAction action)
{
int recalculateStatisticsEveryXMillseconds = 1000;
timerRecalcStatistics = new System.Timers.Timer(recalculateStatisticsEveryXMillseconds);
timerRecalcStatistics.AutoReset = true;
timerRecalcStatistics.Elapsed += new System.Timers.ElapsedEventHandler(TimerRecalcStatisticsElapsed);
timerRecalcStatistics.Interval = recalculateStatisticsEveryXMillseconds;
timerRecalcStatistics.Enabled = true;
this.maxRange = range;
this.hashRunningTotalDB = new HashRunningTotalDB(action);
this.hashesByDate = new HashesByDate(action);
this.dataOverwriteAction = action;
}
private void TimerRecalcStatisticsElapsed(object source, System.Timers.ElapsedEventArgs e)
{
stopwatchForRecalcStatistics.Start();
Console.WriteLine("The TimerRecalcStatisticsElapsed event was raised at {0}", e.SignalTime.ToString("o"));
// DO WORK HERE
stopwatchForRecalcStatistics.Stop();
double timeBuffer = GetInterval(IntervalTypeEnum.NearestSecond, e.SignalTime) - stopwatchForRecalcStatistics.ElapsedMilliseconds;
if (timeBuffer > 0)
timerRecalcStatistics.Interval = timeBuffer;
else
timerRecalcStatistics.Interval = 1;
stopwatchForRecalcStatistics.Reset();
timerRecalcStatistics.Enabled = true;
}
}
I wonder if this lost 1 to 120ms per 1 second cycle means the CPU isn't as efficient as it could be with this implementation.
I have an application which must transmit packets at fixed intervals of 33ms +/- a few milliseconds.
So, I came up with a SpinTimer class shown below:
class SpinTimer
{
public void SpinWait(double waitTimeInSeconds)
{
if (waitTimeInSeconds < 0.0)
{
throw new ArgumentOutOfRangeException("waitTimeInSeconds", "Must be >= 0.0");
}
Stopwatch timer = new Stopwatch();
double elapsed = 0.0;
timer.Start();
do
{
elapsed = (double)timer.ElapsedTicks / (double)Stopwatch.Frequency;
} while (elapsed < waitTimeInSeconds);
}
}
However, after profiling the code, I found that the System.Diagnostics.Stopwatch.GetTimestamp() call was taking most of the execution time. Just as a note, I can't afford to have the thread sleep and context switch as this causes too much "jitter" in the output rate.
Notes about the profile run:
Thread priority was set to ThreadPriority.Highest
Process priority was set to ProcessPriorityClass.High
The original program that I wrote (in C++) accomplished the same effect using the QueryPerformanceCounter() and QueryPerformanceFrequency() functions. Should I be using these calls with PInvoke instead of the Stopwatch class? Or, is there another appropriate way to do this?
Thanks!
The stopwatch is in the diagnostics namespace. It shouldn't be used for performance level timing.
you probably want a Timer.
have you tried using a System.Windows.Threading.DispatcherTimer ?
I've created several programs with this, and never experienced any delay at all
After, some more debugging (inspired by Eric Lippert's comment), I realized that my above code was doing exactly as requested. The problem was with the calling code at a higher level of abstraction feeding it extremely long wait times.
Thanks for the suggestions to use System.Windows.Threading.DispatcherTimer and System.Timers.Timer (I gave both an up-vote); however, after testing each of these, they are limited to ~10 milliseconds of accuracy, which is just not quite good enough for my purposes. But, I did find that my "tight" loop code above is accurate to ~1 microsecond, which is more than enough for my current needs.
An additional resource that others might find helpful is this CodeProject article about increasing the Stopwatch accuracy. The main idea is to essentially reduce the likelihood that your program will endure a context switch, and thus travel through the scheduling queues wasting time.
I have a code which when run, it executes series of lines in sequence.
I would like to add a pause in between.
Currently, I have it like this
//do work
Thread.Sleep(10800000);
//do work
This however freezes the software, and I think it's because sleep time is way too long.
I searched online and I found another work around called Timer.
Can someone show me a sample code for Timer which works just like Thread.sleep?
Thank you in advance.
Edit : I need the software to wait for 3 hours before proceeding with rest of the code execution. This software is meant to communicate with machines, and I cannot let the rest of the code execute while waiting for 3 hours.
Please see this MSDN reference on the System.Threading.Timer class. There is a great explanation, all of the class members, and some sample code for you to follow when testing/learning.
Mind you, though, the Timer should be used when you want to fire an event at a certain interval. If you are just looking to pause execution of your application, then you should go with Thread.Sleep(). However, as many others have pointed out, you are causing your thread to sleep for an extended amount of time.
Your software would freeze if that sleep is on the main thread. Keep in mind the parameter is in milliseconds. 10 800 000 milliseconds = 10 800 seconds
Another way to pass the time is to pass a TimeSpan object instead. Ex:
// Sleep for 10 seconds
System.Threading.Thread.Sleep(new TimeSpan(0, 0, 10));
As for timer:
You can use System.Timers.Timer;
Timer timer = new Timer();
timer.Interval = 20; // milliseconds
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.AutoReset = true; // if not set you will need to call start after every event fired in the elapsed callback
timer.Start();
USE A TIMER!
private DispatcherTimer Timer;
public Constructor
{
Timer = new System.Windows.Threading.DispatcherTimer();
Timer.Tick += new EventHandler(Timer_Tick);
Timer.Interval = new TimeSpan(0,0,10);
Timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
Timer.Stop();
Timer -= Timer_Tick;
Timer = null;
// DO SOMETHING
}
Your problem is that you're blocking the main thread of your application, which is responsible for keeping the ui running. You shouldn't do this. Instead use a timer - the Forms one is probably easiest in a Forms app, or consider BackgroundWorker. (For such a long wait a timer is probably more suitable)
The Thread.Sleep is what you want to use for this, you may want to use a more reasonable sleep period than 3 hours though.
Update:
After reading some of the comments, Thread.Sleep is probably not what you want. Use a System.Threading.Timer instead as others have suggested.
Have a look Thread.Sleep(300) not working correctly
Probably you need to use the "Dispatcher". Have a look here as well
Thread.Sleep would typically be used to pause a separate thread, not in the main thread of your app.
Timer would typically be used to periodically cause the main thread to stop its normal operations and handle an event.
Either method can be used to periodically perform a function after a certain time interval.
What I wouldn't do is ask the main thread to sleep for 3 hours.
I think you should use a Monitor. It helps you to put a wait on objects and release the lock when you need to continue running the program.
You should find your answer here: Safe Thread Synchronization
You can replace
Thread.Sleep(X);
by
Task.WaitAll(Task.Delay(X));
You're sleeping the thread for 10800 seconds, or 3 hours. Thread.Sleep() is designed to freeze your thread, stop anything from working in the software for that duration. In this case, the duration is 18 minutes. What are you trying to do?