Using timer in windows form application - c#

I am new to coding and are having trouble.
I want to use a timer that will start upon pressing ScatterMode tab, it will start counting 4sec before running "Dosomething" function. This cycle will repeat itself until i decide to stop the program. But the problem i get is, this code only run correctly for like 2loop, after that the timer sort of go crazy LOL.
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
//ScatterMode Tab
private void Scatter_modeToolStripMenuItem_Click(object sender, EventArgs e)
{
timer.Interval = 4000;
timer.Enabled = true;
timer.Tick += new EventHandler(Dosomething);
timer.Start();
}
private void Dosomething (object sender, EventArgs e)
{
timer.Stop();
timer.Enabled = false;
Grab.buffer(out buffer, out status, 6000);
Scatter_mode(buffer);
pictureBox1.Refresh();
int done_grab = 1;
if (doneGrab == 1)
{
timer.Interval = 4000;
timer.Enabled = true;
timer.Tick += new EventHandler(Scatter_modeToolStripMenuItem_Click);
timer.Start();
done_grab = 0;
}
}

Adding a new event handler to a timer, to handle its tick event, inside the handler for the tick event will indeed cause the timer to go "crazy". Every time the timer raises its event, another event handler (that responds to events raised) will be added. This means the next time the timer ticks, the event code will run twice. Two new event handlers will be added. Next time the timer ticks, the code will run 4 times. 4 event handlers will be added ... and so on
Remove this line from your code:
timer.Tick += new EventHandler(Scatter_modeToolStripMenuItem_Click);
And move this line into your form's constructor:
timer.Tick += new EventHandler(Dosomething);
You only want to wire this event handler up once. Every time the timer's interval elapses, the code will run, once :)
I'll also do a bit of a peer review of your code, see the comments:
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
//ScatterMode Tab
private void Scatter_modeToolStripMenuItem_Click(object sender, EventArgs e)
{
timer.Interval = 4000; //can go in the constructor also; don't need to set repeatedly
timer.Enabled = true;
timer.Tick += new EventHandler(Dosomething); //move to constructor
timer.Start(); //this isn't needed - you already Enabled the timer, which started it
}
private void Dosomething (object sender, EventArgs e)
{
timer.Stop(); //use this
timer.Enabled = false; //or this. It's not required to do both
Grab.buffer(out buffer, out status, 6000); //if these lines crash then your timer will
Scatter_mode(buffer); //only restart if the toolstripmenuitemclick
pictureBox1.Refresh(); //above runs.. is it what you wanted?
int done_grab = 1; //not needed
if (doneGrab == 1) //this will always evaluate to true, it is not needed
{
timer.Interval = 4000; //the interval is already 4000, not needed
timer.Enabled = true; //careful; your timer may stop forever if the code above crashes
timer.Tick += new EventHandler(Scatter_modeToolStripMenuItem_Click); //remove
timer.Start(); //not needed
done_grab = 0; //not needed
}
}

Related

SImulated mouse scrolling is processed after sleeps

I am using
for (int i = 0; i < 10; i++)
{
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, -10, 0);
System.Threading.Thread.Sleep(1000);
}
to scroll down a bit then wait a second the scroll and so on. However, it seems to wait 10 seconds then scroll down -100.
I am not sure if this is relevant but I am trying to get it to scroll down a page in a web browser as part of a windows form (once you scroll to the bottom the page loads more and you can scroll again).
the problem is that your GUI freezes and is not updated for the duration of the for loop, because it is running on the same thread. To See the changes every second you need to run it on a background thread.
You can also use a System.Timers.Timer to do that job. Set it up as
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.AutoReset = true;
and hook up the Elapsed event in which you handle the scrolling
timer.Elapsed += Timer_Elapsed;
timer.Start();
you would also need a counter like in your for-loop. Count down until 0 with it in the event handler
int counter = 10;
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if(counter > 0)
{
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, -10, 0);
counter--;
}
else
{
System.Timers.Timer t = sender as System.Timers.Timer;
t.Stop();
}
}
This way you can stop the timer after 10 iterations
As suggested by Jakub DÄ…bek you can also use System.Windows.Forms.Timer. This would look like this:
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += Timer_Tick;
timer.Start();
private void Timer_Tick(object sender, EventArgs e)
{
// here the same code as above
}

I need to create a timer based application?

I need to create a application which must have a timer control;
the timer must automatically initialize when each form is called, when the time reach 3 seconds means it must load the another form.
I have tried this:
private void Form1_Load(object sender, EventArgs e)
{
timer1.Start();
if (timer1.Interval = 3000)
{
MessageBox.Show("Times up");
form2 i=new form2();
form2.show();
}
}
but I cant get the correct result....
Timers in C# work by firing events periodically. You need to attach an event handler which responds to the timer event. The MSDN documentation has a straightforward example (code snippet reproduced below).
public Timer aTimer;
public static void Main()
{
// Create a timer with a ten second interval.
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.ReadLine();
}
// Specify what you want to happen when the Elapsed event is
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
initialize and enable your timer and attach an event handler to Tick event.
Timer timer;
private void Form1_Load(object sender, EventArgs e)
{
timer = new Timer();
timer.Enabled = true;
timer.Interval = 3000;
timer.Tick += timer_Tick;
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
MessageBox.Show("Times up");
Form2 i = new Form2();
i.Show();
}

How to pause timer in windows phone?

In this code after starting timer again it starts from the current value instead of the vale it stopped. How to pause this timer?
public Page1()
{
InitializeComponent();
_rnd = new Random();
_timer = new DispatcherTimer();
_timer.Tick += new EventHandler(TimerTick);
_timer.Interval = new TimeSpan(0, 0, 0, 1);
}
void TimerTick(object sender, EventArgs e)
{
var time = DateTime.Now - _startTime;
txtTime.Text = string.Format(Const.TimeFormat, time.Hours, time.Minutes, time.Seconds);
}
public void NewGame()
{
_moves = 0;
txtMoves.Text = "0";
txtTime.Text = Const.DefaultTimeValue;
Scrambles();
while (!CheckIfSolvable())
{
Scrambles();
}
_startTime = DateTime.Now;
_timer.Start();
//GridScrambling.Visibility = System.Windows.Visibility.Collapsed;
}
private void Pause_Click(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
NavigationService.Navigate(new Uri("/Page4.xaml", UriKind.Relative));
_timer.Stop();
}
private void Play_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
_timer.Start();
}
As this says that the Stop method only changes the IsEnabled property and this says that this property only prevents the Tick event to be raised, I don't think that there is a method to simply 'pause' the timer. The best way is to reinitialize the timer each time you have "paused" it, if you really want it to start clean again.
But I do not think that this is you real problem. When you pause your game the timer stops working. When you continue it the timer starts working again. When you now try the calculate the time from THIS moment till the start time, then you make a big mistake: you have to ignore the paused time. Because when you play the game 2s, then pause it for 10s and then continue the game, the timer shows 12s, instead of 2s, doesn't it? Maybe you should store the paused times in a variable and substract that from the real game time.

C# timer I can speed up but not slow down

I have a timer event setup and I would like to change how often the timer event happens by reading a number from a text box. If the box is '10' and you click the update button the event would trigger every 10ms then if you changed to '100' and clicked it would happen every 100ms and so on.
When I run the program however, i can speed up the event frequency (e.g. 100ms to 10ms) but I cannot slow it down (e.g. 10ms to 100ms). Here is the piece of my code that changes the timer when I click:
private void TimerButton_Click(object sender, EventArgs e)
{
getTime = ImgTimeInterval.Text;
bool isNumeric = int.TryParse(ImgTimeInterval.Text, out timerMS); //if number place number in timerMS
label2.Text = isNumeric.ToString();
if (isNumeric)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Enabled = false;
timer.Interval = timerMS;
timer.Elapsed += new ElapsedEventHandler(timerEvent);
timer.AutoReset = true;
timer.Enabled = true;
}
}
public void timerEvent(object source, System.Timers.ElapsedEventArgs e)
{
label1.Text = counter.ToString();
counter = (counter + 1) % 100;
}
If anyone knows what I may be doing wrong it would be greatly appreciated.
The problem with this code is, that you create a new Timer each time you click the button. Try to create the timer outside the method. You think it's only goes faster, but instead multiple timers trigger the timerEvent
private System.Timers.Timer _timer;
private void CreateTimer()
{
_timer = new System.Timers.Timer();
_timer.Enabled = false;
_timer.Interval = 100; // default
_timer.Elapsed += new ElapsedEventHandler(timerEvent);
_timer.AutoReset = true;
_timer.Enabled = true;
}
private void TimerButton_Click(object sender, EventArgs e)
{
bool isNumeric = int.TryParse(ImgTimeInterval.Text, out timerMS); //if number place number in timerMS
label2.Text = isNumeric.ToString();
if (isNumeric)
{
_timer.Interval = timerMS;
}
}
public void timerEvent(object source, System.Timers.ElapsedEventArgs e)
{
label1.Text = counter.ToString();
counter = (counter + 1) % 100;
}
Make sure that the CreateTimer is called in the constructor/formload. Also you can now stop the timer within another button event. With _timer.Enabled = false;
You're always creating a new timer and never stopping the old timer. When you "change" it from 100 to 10 your 100ms timer is still firing every 100 ms, so every 100ms two timers are firing at around the same time.
You need to "remember" the old timer so that you can stop it. Or, better yet, just have only one timer that you change the interval on.
private System.Timers.Timer timer = new System.Timers.Timer();
public Form1()
{
timer.Enabled = false;
timer.AutoReset = true;
timer.Elapsed += timerEvent;
}
private void TimerButton_Click(object sender, EventArgs e)
{
getTime = ImgTimeInterval.Text;
bool isNumeric = int.TryParse(ImgTimeInterval.Text, out timerMS); //if number place number in timerMS
label2.Text = isNumeric.ToString();
if (isNumeric)
{
timer.Interval = timerMS;
timer.Enabled = true;
}
}
Well the basic problem is that you're building a new one every time. Make a private timer:
private System.Timers.Timer _timer = new System.Timers.Timer();
and then fix it up when the button is clicked:
if (isNumeric)
{
_timer.Stop();
_timer.Interval = timerMS;
_timer.Start();
}
and then in the .ctor, do this:
_timer.Elapsed += new ElapsedEventHandler(timerEvent);
Now you have a single timer that you are just modifying as the user changes the value in the text box.

Getting time until next event

I have a sync timer in my app that fires up a function at a given time... now I want to know how much time is left until the next call to that function.
This is my call to the timer:
var syncTime = time.activitylog;
double time = TimeSpan.Parse(syncTime).TotalMilliseconds;
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += new ElapsedEventHandler(DisplayTimeEvent);
myTimer.Interval = time;
myTimer.Start();
How do I get the time until next call?
Thanks
You can use another timer, and set the Interval of that the value that you want,exactly a part time of the Interval of original timer.
Then start them Simultaneously,I mean at the same time.
UPDATE :
Maybe this code describes my solution better :
public Form1()
{
InitializeComponent();
}
System.Windows.Forms.Timer trOriginal = new System.Windows.Forms.Timer();
System.Windows.Forms.Timer trRemain = new System.Windows.Forms.Timer();
double remain = 0;
private void button1_Click(object sender, EventArgs e)
{
trOriginal.Interval = 1000;
trRemain.Interval = 1;
trOriginal.Tick += new EventHandler(trOriginal_Tick);
trRemain.Tick += new EventHandler(trRemain_Tick);
trOriginal.Start();
trRemain.Start();
}
void trRemain_Tick(object sender, EventArgs e)
{
remain -= trRemain.Interval;
Console.WriteLine("remain MS to next event : " + remain);
}
void trOriginal_Tick(object sender, EventArgs e)
{
remain = trOriginal.Interval;
}
You can use a System.Diagnostics.Stopwatch to keep track of how much time has passed already and restart the Stopwatch with every tick of your Timer.
Stopwatch watch = new Stopwatch();
private void DisplayTimeEvent(object sender, EventArgs e)
{
watch.Restart();
// Whatever is supposed to happen, when the timer ticks
}
Now whenever you want to know how much time is left until the event is fired next, you can do this:
long timeLeft = myTimer.Interval - watch.ElapsedMilliseconds;

Categories

Resources