Timer Interval Is Smaller Than Function In Tick Event - c#

I have a timer with 10 seconds interval and on timer_Tick event I do some stuff which usually needs about a second, but sometimes it needs More than 90 seconds. How will it act? Is this event synchronous to wait for the eventhandler to finish executing? I tested but still I need an answer...
private void checkTimer_Tick(object sender, EventArgs e)
{
MessageBox.Show("Test");
for (int i = 0; i < 2000000000; i++)
{
}
MessageBox.Show("Test");
}
when i test it after first tick MessageBox is shown. I don't click OK and wait for another tick. And another MessageBox is shown on the seconds tick and so on...
in MSDN Documentation I read that it is synchronous... Any Idea?

I solved it by adding timer disabling at the beginning of tick event and enabling at the end of tick event. like this
private void checkTimer_Tick(object sender, EventArgs e)
{
checkTimer.Enabled = false;
MessageBox.Show("Test");
for (int i = 0; i < 2000000000; i++)
{
}
MessageBox.Show("Test");
checkTimer.Enabled = true;
}

I see nothing in the System.Windows.Timers Documentation that you linked to that mentions it being synchronized. If you want each Tick event to wait to the previous Tick Event has finished. Stop the Timer at the start of your handler and restart in after your work is done. That is what the MSDN documentation shows.

Related

I am stuck in my while loop with elapsed time of a timer as condition

I am starting a timer and I want the method to wait until some time passed. I have searched in other similar questions but cannot find a clear answer.
Why is does the following code freeze the app?
elapsed time starts at 0 and intervall is 1000 (1sec)
private void timer2_Tick(object sender, EventArgs e)
{
elapsedtime2++;
}
//this is inside my method
timer2.Start();
while (elapsedtime2 < 3)
{
}
timer2.Stop();
The easiest way to pause execution for a second is:
Thread.Sleep(1000);
If you're familiar with async/await, the async equivalent is:
await Task.Delay(1000);
You can use events to get the desired behaviour:
private int elapsedtime2 = 0;
private ManualResetEventSlim mre = new ManualResetEventSlim();
private void timer2_Tick(object sender, EventArgs e)
{
elapsedtime2++;
if(elapsedtime2 >= 3)
{
mre.Set();
}
}
If your elapsed time variable has the expected value, you can set the event.
mre.Reset();
timer2.Start();
mre.Wait();
timer2.Stop();
Before you start the timer, you unset the event. After you started your timer, you wait until the event is set.

What event is responsible for actions when time is out in Timer Control?

My program is some kind of test. The time of passing test is limited(20 minutes). When the time is out, the test must be finished and MessageBox appears with results of test. In Form_Load :
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = (1000) * (1);
timer1.Enabled = true;
timer1.Start();
private void timer1_Tick(object sender, EventArgs e)
{
timer_label.Text = Convert.ToString(time);
--time;
}
How to finish test when time == 0? And why time in timer_label changes with step 2?(e.g. 1999, 1997, 1995...)
How to finish test when time == 0?
Timer just raises even on some interval. You should start timer for that. If you don't want events to be raised anymore, you should stop timer. You can do it directly in Tick event handler:
private void timer1_Tick(object sender, EventArgs e)
{
timer_label.Text = Convert.ToString(time);
time--;
if (time == 0)
timer1.Stop();
}
Second question:
And why time in timer_label changes with step 2?(e.g. 1999, 1997,
1995...)
From your code there is no reason for such behavior. Looks like you have subscribed to two timers, or you have two event handlers of same timer Tick event. Also make sure you don't have decrement operator when displaying time, something like this:
timer_label.Text = Convert.ToString(--time);
--time;

C# Timer not resetting from one click to another

I need to store the piano duration with Ticks as so then make the music note show according to that duration (Music players would know).
I'm using an interval of 100, but for some testing I used it at 1000.
The problem is this. When I'm invoking the method (I'm taking the 1000 millisecond interval one) the timer starts.. if I DO NOT manage to get the 1000 milliseconds it shows Duration 0: but then if I do for example 2 seconds, it shows 3 seconds, if I try to press it for another second (a different key) it would show 4 seconds instead of 1.
It's like it keeps on recurring. Same happened with the 100 interval one. It went mad. sometimes 40 sometimes 23 and so on. Any idea how to fix (resetting the timer)
N.B I'm using System.Windows.Forms.Timer as library
part of a method which invokes the methods further below
for (int i = 0; i < 15; i++)
{
WhiteKey wk = new WhiteKey(wKeys[i], wPos[i]-35,0); //create a new white Key with [i] Pitch, at that x position and at y =0 position
wk.MouseDown += onRightClick; //holds the Duration on Right Click
wk.MouseUp += onMouseUp;
wk.Click += new EventHandler(KeyClick); //Go to KeyClick Method whenever a key is pressed
this.panel1.Controls.Add(wk); //Give it control (to play and edit)
}
Methods controlling the time
private void onRightClick(object sender, MouseEventArgs e)
{
wk = sender as WhiteKey;
duration = 0;
t1.Enabled = true;
t1.Tick += timeTick;
t1.Interval = 100;
}
private void timeTick(object sender, EventArgs e)
{
duration++;
}
private void onMouseUp (object sender, MouseEventArgs e)
{
t1.Enabled = false;
String time = "Key: " + pitch + "\nDuration: " +duration ; //Test purposes to see if timer works
MessageBox.Show(time);
}
You are trying to measure time, don't use Timer, use Stopwatch.
You can find C# Stopwatch Exmples at dotnetpearls.com.
In abstract this is what you would want to do is something like this:
private void onRightClick(object sender, MouseEventArgs e)
{
stopwatch.Reset();
stopwatch.Start();
}
private void onMouseUp (object sender, MouseEventArgs e)
{
stopwatch.Stop();
String msg = "Duration in seconds: " + (stopwatch.ElapsedMilliseconds / 1000.0).ToString("0.00");
MessageBox.Show(msg);
}
Note: you may want to change the units or the string format.
Notes on using timer:
1) System.Windows.Forms.Timer uses the message loop of your window, this means that it may get delayed because the window is busy handling other events (such as click). For a better behaviour use System.Threading.Timer.
2) If using System.Windows.Forms.Timer don't set the Tick event handler each click. The event handler will execute once for each time you add it.
That is:
private void onRightClick(object sender, MouseEventArgs e)
{
wk = sender as WhiteKey;
duration = 0;
t1.Enabled = true;
//t1.Tick += timeTick; you should add this only once not each click
t1.Interval = 100;
}
3) If you use System.Threading.Timer you may want to make the variable duration volatile.
t1.Tick += timeTick;
By the way in your code sample you subscribe to the 'Tick' timer event each time on Right mouse click.
So if you click 2 times the
private void timeTick(object sender, EventArgs e)
method will be called twice, and 'duration++' will be executed twice. Your event subscription code should be executed only once for the timer.
P.S. If you need to measure duration, Timer is not the best way to do it.

c# timer strange behavior

private void aMethod()
{
aTimer = new System.Timers.Timer(3000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimerEvent);
aTimer.Enabled = true;
aTimer.Start();
}
private void button4_Click(object sender, RoutedEventArgs e)
{
fileEntries = Directory.GetFiles(#"C:\Users\John\Documents\Visual Studio 2010\Projects\ComeOn\ComeOn\bin\Debug\come");
aMethod();
index = 0;
}
private void OnTimerEvent(Object sender, ElapsedEventArgs e)
{
Bitmap LogoImg = new Bitmap(fileEntries[index]);
LogoImg.MakeTransparent(LogoImg.GetPixel(1, 1));
this.Dispatcher.Invoke(
new Action(() => image1.Source = GetBitmapSource(LogoImg)));
index++;
}
The length of fileEntries is 3. I created a timer which will start on 3 seconds. First it will execute image1.Source = GetBitmapSource(LogoImg)//for fileEntries[0] for 3 seconds, then for fileEntries[1] for 3 seconds and in the end fileEntries[2] for 3 seconds.
But, my program does this:
Start the timer, run fileEntries[0], fileEntries[1] and fileEntries[2] for 0.05 seconds, then wait 3 seconds, then start again. Why is this?
How often did you click that button?
Every time you press the button, a new event handler will be hooked to the timer. You never unsubscribe the event handler.
You should either prevent the button from being clicked while you are performing the required work, or you should unsubscribe before subscribing again.
As Hans Passant states in his comment, you should probably also look into using a BackgroundWorker.
You shouldn't do
aTimer = new System.Timers.Timer(3000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimerEvent);
aTimer.Enabled = true;
aTimer.Start();
more than once. Do it in Form_Load event, or in constructor. in your OnTimerEvent event, prevent your code from being executed when files aren't initialized, for example
int index = -1;
private void OnTimerEvent(Object sender, ElapsedEventArgs e)
{
if(index != -1)
{
Bitmap LogoImg = new Bitmap(fileEntries[index]);
LogoImg.MakeTransparent(LogoImg.GetPixel(1, 1));
this.Dispatcher.Invoke(
new Action(() => image1.Source = GetBitmapSource(LogoImg)));
index++;
}
if (index == 3) // when all 3 were loaded, reset index. You can also stop the timer if you won't be loading files the second time
{
index=-1;
}
}
Or you should unsuscribe before you add new event handler. But keeping track of how many event handlers are added to an event is tricky (or I should say I havn't found a way to do it yet).
As #Steven Jeuris said, when an event handler is added to an event, it is literaly ADDED, to event handlers LIST. So every time when your timer elapses every event handler on the list is executed, which means if there are 3 event handlers added (as in your case) the event handler method will execute 3 times.

Timer (winforms)

i want timer to run a counter from 0 to 3. i added the timer from the toolbox in visual basics 2008 (instead of creating an object and using properties) you can see the Timer at the bottom of the winform..
int timerCounter;
private void animationTimer_Tick(object sender, EventArgs e)
{
//timer should go 0,1,2,3..and then reset
while (true)
{
timerCounter++;
if (timerCounter > 3)
{
timerCounter = 0;
}
game.Twinkle();
//screen gets repainted.
Refresh();
}
}
will the timer work?
(i enabled it and set it to 33 milliseconds)
Set the timer's interval to 1000 (which is 1000ms or 1 second). Then when you enable it, it'll go on and on and on, firing the timer1_tick event every time it goes through the interval.
Here's an example on how to do it:
int count = 0;
private void timer1_Tick(object sender, EventArgs e)
{
count++;
if (count == 3)
{
//Do something here, because it's the third toll of the bell.
//But also reset the counter after you're done.
count = 0;
}
}
Don't forget to .Enable the timer!

Categories