In my application I'm using two Timer, each Timer use a BackgroundWorker. Here the declaration:
DispatcherTimer timer1 = new DispatcherTimer();
DispatcherTimer timer2 = new DispatcherTimer();
BackgroundWorker worker1 = new BackgroundWorker();
BackgroundWorker worker2= new BackgroundWorker();
I using timer1 for perform an heavy method with a BackgroundWorker and timer2 for execute another BackgroundWorker that check the content of a file.
In this way I assign the event to BackgroundWorkers:
worker1.DoWork += worker_DoWork;
worker1.RunWorkerCompleted += worker_RunWorkerCompleted;
worker1.WorkerSupportsCancellation = true;
worker2.DoWork += worker_DoWork2;
worker2.RunWorkerCompleted += worker_RunWorkerCompleted2;
worker2.WorkerSupportsCancellation = true;
Now timer1 have a range of 15 minutes so the BackgroundWorker execute the heavy method each 15 minutes. And timer2 have a range of 1 second. With the timer1 all working good, but the problems are coming when I've added the timer2.
As I said before this timer allow me to start a method that read a file through the worker2, this file have a property, if this property change I need to perform some special activity. Until here no problem.
What I did is the following:
//This method is called by MainWindow
public ReadFile()
{
//before this I already assigned to timer1 the tick event and start
timer2.Tick -= new EventHandler(Event_Tick);
timer2.Tick += new EventHandler(Event_Tick);
timer2.Interval = new TimeSpan(0, 0, 1);
timer2.Start();
}
This is the Tick event associated to timer2
private void Event_Tick(object sender, EventArgs e)
{
if (!worker1.IsBusy) //I skip the reading, worker1 is busy
{
timer1.Stop(); //stop the first timer
worker2.RunWorkerAsync();
}
else
{
Console.WriteLine("worker1 is busy!");
}
}
I don't need to add here the DoWork, is just a parsing of a file, very useless for the question. When worker2 complete the task I did this:
private void worker_RunWorkerCompleted2(object sender, RunWorkerCompletedEventArgs e)
{
timer1.Start();
ReadFile();
}
How you can see I start the timer1 again, and execute again the ReadFile method. Now if timer1 has reached the interval, so 15 minutes has passed, should execute the timer1.Tick += new EventHandler(Heavy_Tick); that execute the DoWork to worker1. But the timer1 never start.
I can't figure out to this, what am I doing wrong?
Now I get it!
You want to execute worker1 every 15 minutes and worker2 every second but only when worker1 is not busy. Your problem is this here:
if (!worker1.IsBusy) //I skip the reading, worker1 is busy
{
timer1.Stop(); //stop the first timer
worker2.RunWorkerAsync();
}
and this:
public ReadFile()
{
//before this I already assigned to timer1 the tick event and start
timer2.Tick -= new EventHandler(Event_Tick);
timer2.Tick += new EventHandler(Event_Tick);
timer2.Interval = new TimeSpan(0, 0, 1);
timer2.Start();
}
Set both timer intervals and tick event handlers during startup, e.g. Form_Load()or at the beginning of Main(). Start them there too. You should not have to stop any timer at all!
By setting the interval, all you have to do is handle the Tick() event. Remove your .Start() and Stop() calls from your WorkerCompletedand Tick methods and you should do fine.
So a lot could be going on here but you should make sure that:
You timer isn't storing it's old progress and you are checking for a certain length of time before stopping. This will automatically cause the timer to stop when restarting.
The timer.stop() function is not disposing your object to an un-restart-able state.
You aren't accessing the timer variable through some pointer that is maintain a stopped value. (Unlikely but annoying when it happens)
I'd personally consider just pausing the timer and resetting the progress, instead of fully stopping it since this is causing issues.
Related
Fairly new to C# and timers, although I've managed to do some really fun stuff in C#, however I'm not getting the hang of Timers.
Form1.cs:
private int counter;
static System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
public void goTimer()
{
// Set Counter
counter = 60;
// If timer is already enabled, stop it.
if (timer1.Enabled)
{
timer1.Dispose();
//timer1.Stop() <- also tried
}
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 1000; // 1 second
timer1.Start(); // Timer exists
txtCountdown.Text = counter.ToString();
}
private void timer1_Tick(object sender, EventArgs e)
{
counter--;
if(counter == 0)
{
timer1.Stop();
}
txtCountdown.Text = counter.ToString();
}
So, what happens is that it seems to work as intended, until you start calling goTimer(); from e.g. a button press, then it will speed up the (int) counter as many times as you pressed it... And after a while the memory will be eaten up.
In this case the users will be able to do call the timer function, as it will remove some objects, clear some data and refresh the session, but also when the timer reaches 0.
Using Winforms, I did not add a timer in visual studio (it's only referenced here in Form1.cs).
How do I terminate all timers, and then restart at (int) counter?
Using start and stop of the timer would be the proper aproach, but generally also the dispose variant will work.
Your memory hole results from the multiplied event handler assignments, you need to move this method to your constructor or some other initialization method:
timer1.Tick += new EventHandler(timer1_Tick);
If you really want to create a new timer every time, you need to release the event handler before:
timer1.Tick -= timer1_Tick;
First of all, as MichaelSander already mentioned, you should put these lines in your Form1.cs constructor:
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 1000; // 1 second
Secondly, there is no point in disposing your timer if it's meant to be used more than once. Instead of timer1.Dispose() you should use timer1.Stop() just like you do in your timer1_Tick handler. Also there is no point in checking whether the timer is enabled or disabled as both timer1.Start() and timer1.Stop() will either turn it on/off respectively or do nothing at all. That means that in your case you can remove this block completely:
if (timer1.Enabled)
{
timer1.Dispose();
}
I want to show timer on UI such that when aplication star executing timer starts with 00:00:00 and when it completed its execution timer stops. Timer should show timing per second while running.
You can use the System.Windows.Forms.Timer, which is created for scenarios like yours. You can read more about in MSDN.
You should use the following code snippet as sample:
Timer timer = new Timer();
timer.Interval = 1000;
timer.Tick += new System.EventHandler(timer_Tick);
timer.Start();
private void timer_Tick(object sender, System.EventArgs e)
{
this.Text = string.Format("{0:hh:MM:ss}", DateTime.Now);
}
Notice that you should dispose the Timer when you do not needed.
I'm trying to figure out a way in Silverlight / C# to make a DispatchTimer run only once.
I have a user form and when submitted I want to display a message for 10 seconds and then disappear and kill the DispatchTimer thread.
I know how to make a DispatchTimer that repeats:
clock.Interval = TimeSpan.FromSeconds(10);
clock.Tick += clockTick;
clock.Start();
But I want that thread to end as soon as it completes.
This should work for you:
DispatcherTimer clock = new DispatcherTimer();
clock.Interval = TimeSpan.FromSeconds(10);
clock.Tick += (object sender, EventArgs e) =>
{
clock.Stop();
// Some code here
};
clock.Start();
An anonymous event handler will also keep things "in the same place" in case you don't want to widen the scope of your DispatcherTimer object.
Stop the timer in your clockTick handler once it fires.
I have a method that I want to call a method (will mention as myFanc) in seperated thread every 3 seconds
The code below can easly do it,
Timer myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler( myFanc );
myTimer.Interval = 3000;
myTimer.Start();
The code above may cause myFanc to be called while another call to myFanc isn't finished yet
My problem is that I also want myFanc to finished before I will call her agian, so basically I want to call the method in seperated thread every 3 seconds after myFanc is finished, how can I do it?
I don't mind if the solution won't use Timer class, I just want this behavior to work..
Set the AutoReset property of your timer to false, then, at the end of your event handler (i.e. "myFanc"), call the Start method of your timer again.
Do not use a timer, loop in the thread calling "myfanc" and use
Thread.Sleep(3000);
to insert the desired delay.
At the top of myFunc put this
myTimer.Enabled = false;
and at the end when it is finished put this
myTimer.Enabled = true;
It will cause that you will temporairly disable the Timer while function is executing
This is the solution I used - thanks to Jim
using System;
using System.Timers;
using System.Threading;
class myApp
{
public static void Main()
{
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += new ElapsedEventHandler( myFanc );
myTimer.Interval = 1000;
myTimer.AutoReset = false;
myTimer.Start();
while ( Console.Read() != 'q' )
{
; // do nothing...
}
}
public static void myFanc(object source, ElapsedEventArgs e)
{
Console.Write("\r{0}", DateTime.Now);
Thread.Sleep(3000); //the sleep here is just to test the method, wait to be finished before another call the myFanc method is being performed
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += new ElapsedEventHandler(myFanc);
myTimer.Interval = 1000;
myTimer.AutoReset = false;
myTimer.Start();
}
}
2 methods than I can think of right now
Stop and start the timer inside the myFanc method This ensures 3 seconds between each run
Wrap your code in myFanc inside a lock, this will just skip a turn if it's not finished.
Make sure you use the correct timer.. system.threading.timer is a seperate thread. The timer class in windows.forms (or something like that) isn't
Use a thread and Thread.Sleep(x) like so
Thread thread = new Thread(new ThreadStart(myTimer));
thread.Start();
void myTimer()
{
while (!exit)
{
myFunc();
Thread.Sleep(3000);
}
}
Can i create successfully a timer clock on a thread? i'm creating one but it doesn't seem to work that well. My app is a multi-thread app that has to start a timer on a thread when ever a certain event happens. The timer is placed in every client connection. The clock doesn't work until i close my winform(i don't know why) . Is there anything in particular that i should know about timers in threads ?
Here is my timer code :
timer1.Interval = 1000;
timer1.Tick += new EventHandler(timer_Tick);
timer1.Enabled = true;
timer1.Start();
You might try to use System.Threading.Timer, which is basically a timer that's in a separate thread. You might also consider using a WaitHandle that's never fired and then using WaitOne(1000, false) to wait for a second.
Try this:
public void EnableTimer()
{
if (this.InvokeRequired)
this.Invoke(new Action(EnableTimer));
else
this.timer1.Enabled = true;
}