I would like to implement some timers into my application.
My goal is to provide an easy way to execute some function every x seconds/minutes so I thought about implementing a 1 sec, 5 sec and 15 seconds timer.
The first thing i would like to update every 1 second is the built in clock (don't know if there is any other solution in c#, used this method in c++)
Another use would be e.g. a sync function etc. which shall be executed every xx seconds.
My question is if there are any useful tutorials on this topic? It is the first time that I would like to implement such an timer system into one of my applications and I do not know if there are any things I have to keep in mind.
Thank you in advance for any answer :)
There are various types of Timer classes you can use.
In WPF, if this is for updating something user interface related, you would typically use a DispatcherTimer.
You could also use a System.Timers.Timer or System.Threading.Timer, but realize that this will fire on a background thread, and not on the main user interface thread. This is often beneficial (you don't wait or block your UI if there is "work" happening in the Timer's Tick event or callback), but you also have to remember to marshal anything user interface related back to the UI thread.
// This timer runs on UI thread
System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = System.TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
void timer_Tick(object sender, System.EventArgs e)
{
Title = System.Windows.Input.Keyboard.FocusedElement.GetType().ToString();
}
Related
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.
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?
I have a Windows Application. We have implemented AutoSave functionality as background process.
Sample code is as below:
While(1)
{
Thread.Sleep(60000) // 1 minute sleep
DoAutoSaveAllControls();
}
I think this is bad functionality. Correct me if I am wrong. But, I want to improve performance and do this task after certain time interval, without doing Sleep.
Also, is it good to do this in background process?
A much better approach would be to use a timer. You can find out about the various different timers in the .NET framework from this excellent article:
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
You are using WinForms, so a System.Windows.Forms.Timer will be just fine for you.
For example:
System.Windows.Forms.Timer tmrWindowsFormsTimer = new System.Windows.Forms.Timer();
tmrWindowsFormsTimer.Interval = TimeSpan.FromMinutes(1);
tmrWindowsFormsTimer.Tick += new EventHandler(tmrWindowsFormsTimer_Tick);
tmrWindowsFormsTimer.Start();
private void tmrWindowsFormsTimer_Tick(object sender, System.EventArgs e) {
tmrWindowsFormsTimer.Stop();
DoAutoSaveAllControls();
}
This stops the timer after the first tick, effectively a fire-once timer.
You can use Reactive Extenssions for this as well.It looks more natural and you can combine observables.
var observable = Observable.Timer(
TimeSpan.FromMinutes(1),
TimeSpan.FromMinutes(1)).Timestamp();
using (observable.Subscribe()))
{
DoAutoSave();
}
Thread.Sleep does not affect performance at all. In order to me is perfectly ok, but since your application is probably modifying the document in the UI thread you probably need to sincronize the save in order to avoid concurrent modifications. Just for this reason maybe it would be better to use a Timer instead of BackGroundWorker.
You're right, it's not really a good use of a thread. Take a look at the Timer class.
You can use System.Timers.Timer to start a process after certain interval, check the sample snippet
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(YourHandlerMethod);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
I think you need to trigger save functionality from the calling code (that knows if any changes had already happaned). So that saving thread could know for sure that calling thread has made some changes to save.
This is not an answer for this question, just maybe recommendation. So if you are calling Save from inside of timer, you should verify first if any change happened. To do that you'll need some additional variable, that would be common for working thread and saving thread. If working thread did change something, it triggers that var to true. When saving, if var is true - then saving is needed. After saving - change common var to false.
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.
I want a program to stop executing for a certain amount of time. And i want this to happen in regular intervals. For example, i want a program to run for 5 minutes and then it should stop for 2 mintues and continue running for another 5 minutes after that. Is this possible with the C# Timer class?
You're looking for Thread.Sleep() passing in the number of milliseconds to pause execution for.
I'm not sure this is desirable behaviour, so if you update your question you might get a better answer than this.
You can use a timer that does little more than toggle a variable (e.g. bool). If that bool is used by the application, then you can use it to control whether the application is "running".
I'm suggesting this instead of Thread.Sleep() because at least your application is still responsive. If you want to pause a non-UI thread, then Thread.Sleep() will suffice, but don't call Thread.Sleep() on the UI thread, even with very short durations.
As previous answer say: what is 'stop'? The user can't use the program for 2 minutes? If so you could pop a modal dialog (with text) and the user can't close it.
If this is a Windows Forms application, you might want to consider moving this into a threaded execution model. You can do this using either the BackgroundWorker control, thread pooling with the ThreadPool class, asynchronous methods Begin and End (such as Stream.BeginWrite), or by manually handling the thread yourself (bit more complex).
A BackgroundWorker will provide the easiest form of development by allowing you to handle events for the asynchronous code, and update a progress bar or label to show the current state of the execution. This will allow you to use Thread.Sleep without the system warning the user that the application has hung.
Basically, in Windows Forms development you should be using some form of threading to handle long executions.
You can use Window.Forms.Timer to register a callback each 1000ms
private int counter;
void StartTimer()
{
counter = 0;
Timer timer = new Timer();
timer.Interval = 1000;
timer.Enabled = true;
timer.Tick += Timer_Tick;
}
In the event function simply increment a global counter variable that executes when
a condition fulfills
private void Timer_Tick(object sender, EventArgs e)
{
counter++;
}