Timer continuously firing in C#, Not able to stop - c#

Could any one help me to stop my timer in windows form C3 application? I added timer in form using designer and interval is set as 1000; I would like to do some actions after 5 seconds of waiting after button click. Please check the code and advise me. Problem now is I get MessageBox2 infinitely and never gets the timer stop.
static int count;
public Form1()
{
InitializeComponent();
timer1.Tick += timer1_Tick;
}
public void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
while(count>5)
{
....dosome actions...
}
}
private void timer1_Tick(object sender, EventArgs e)
{
count1++;
MessageBox.Show("Messagebox2");
if (count1 == 5)
{
//timer1.Enabled = false; timer1.Stop();
((System.Timers.Timer)sender).Enabled = false;
MessageBox.Show("stopping timer");
}
}

I would render the count useless and just use the timer 1 interval property and put your actions in the timer1_Tick event.
public void button1_Click(object sender, EventArgs e)
{
timer1.Interval = 5000;
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
MessageBox.Show("stopping timer");
// Your other actions here
}

You are incrementing count1 and checking count.
while(count1 > 5)
{
...dosome actions...
}

Which Timer do you use? Because C# supports class Timer from two different namespaces. One is from Forms, the other is from System.Timers. I would suggest you to use the other one - System.Timers.Timer.
Timer t = new Timer(20000); // created with 20seconds
t.Enabled = true; // enables firing Elapsed event
t.Elapsed += (s, e) => {
\\do stuff
};
t.Start();
In this short code you can see how the timer is created and enabled. By registering to the Elapsed event you explicitly say what to do after the time elapses. and this is done just once. Of course, there are some changes needed in case user clicks button before your limit is reached. But this is highly dependent on behavior of the action you demand.

Related

Remove or Replace Invoke Delegate C#

Before all. I'm not so good at this and hopefully you will understand it anyway.
Im making a function in my program where it checks to see if a row in a rtb is highlighted. If not, it highlights it.
For this to work I had to use different threads to be able to access the rtb from different places. My problem is that it creates a new "delegate"/instance/thread every time the timer refreshes. I would like to remove the old thread/delegate or replace it with the new.
Because now the program crashes after a while. It's a very small program but after 40 sec i reach over 3gb ram usage.
Thanks in advance!
Haris.
Code:
private void Timer()//Timer for color refresh
{
aTimer = new System.Timers.Timer(300);
aTimer.Elapsed += new ElapsedEventHandler(Form1_Load);
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private void RefreshColor()//Refreshing the color of selected row
{
this.Invoke((MethodInvoker)delegate
{
if (richTextBox1.SelectionBackColor != Color.PaleTurquoise)
{
HighlightCurrentLine();
}
});
}
private void Form1_Load(object sender, EventArgs e)
{
Timer();
RefreshColor();
What is happening if i am not mistaken is that you are creating and starting new timers exponentially. So your forms loads, Form1_Load method is called. Form1_Load creates a new timer that when elapsed, will call Form1_Load again. As the old timer not being disposed 2 timers are running now that will both create 2 new timers. 4 timers create 4 new so there are 8, 16, 32 and so on...
Basically what you have to do is call other method on timer elapsed:
private void Timer()//Timer for color refresh
{
aTimer = new System.Timers.Timer(300);
aTimer.Elapsed += ATimer_Elapsed;//new ElapsedEventHandler(Form1_Load);
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private void ATimer_Elapsed(object sender, ElapsedEventArgs e)
{
RefreshColor();
}
private void RefreshColor()//Refreshing the color of selected row
{
this.Invoke((MethodInvoker)delegate
{
if (richTextBox1.SelectionBackColor != Color.PaleTurquoise)
{
HighlightCurrentLine();
}
});
}
private void Form1_Load(object sender, EventArgs e)
{
Timer();
RefreshColor();
Timer(); is only called ones thus creating only one timer.

Timer tick events does not fire in a backgroundworker do_work

I have a background worker which i am using to perform some task. Its working as expected. However, i have a timer that i want to add and make it start the bw and counting like 10 seconds after page load. I put my timer.Interval to 10000. the timer has a tick events as below
private DateTime dateETA;
private void TimerEventHandler(object sender, EventArgs e)
{
while (bw.CancellationPending ==false)
{
if (timerPro.Enabled == true)
{
dateETA = Convert.ToDateTime("1/1/0001 00:00:00");
dateETA = dateETA.AddMilliseconds(timerPro.Interval);
lblETA.Visible = true;
lblETA.Text = "Elapsed Time : " + Convert.ToString(dateETA.TimeOfDay);
// SetText("timer");
}
}
}
My background worker async is on the page contructor method and therefore run on load. just like below
if (bw.IsBusy != true)
{
this.btnPause.Enabled = true;
this.btnStop.Enabled = true;
btnStart.Enabled = false;
// timerPro.Start();
bw.RunWorkerAsync();
}
I wanted to start the timer together with my task therefore i put it before my bw.async . Then i realized the timer tick events does not fire when put before or within the dowork method of the background worker. I thought may be the bw thread is blocking the event from firing then i use an invoke method like below within the dowork in my attempt to start the timer or trigger the tick event of the timer.
this.Invoke((MethodInvoker)(() => { timerPro.Enabled = true; }));
It still does not fire. I am confused and any help or alternative would be appreciated.
I think you just want a running elapsed timer while the backgroundworker does its thing?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();
private void Form1_Load(object sender, EventArgs e)
{
timerPro.Interval = 1000;
timerPro.Tick +=new EventHandler(TimerEventHandler);
SW.Start();
timerPro.Start();
bw.RunWorkerAsync();
}
private void TimerEventHandler(object sender, EventArgs e)
{
lblETA.Visible = true;
TimeSpan TS = SW.Elapsed;
string elapsed = String.Format("{0}:{1}:{2}", TS.Hours.ToString("00"), TS.Minutes.ToString("00"), TS.Seconds.ToString("00"));
lblETA.Text = "Elapsed Time : " + elapsed;
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
// ... do some work ...
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
timerPro.Stop();
}
}

c# stop button for beep sound

I created a simple C# app that uses the beep console. I want to add a stop button to stop the beeping, but once the app starts to run it doesnt let me hit a close/button button. Below is the code i have.
private void button1_Click(object sender, EventArgs e)
{
int int1, int2, hours;
int1 = int.Parse(txtbox1.Text);
int2 = int.Parse(txtbox2.Text);
hours = ((60 / int1) * int2);
for (int i = 0; i <= hours; i++)
{
Console.Beep();
Thread.Sleep(int1 * 60000);
}
}
The reason is that you execute button1_Click in the GUI thread. When you call this method the thread will be stuck there for quite some time because you make it sleep.
If you remove Thread.Sleep(int1*60000); you will notice that your application is unresponsive until it is done beeping.
You should try to use a Timer instead. Something like this should work (this is based on the Windows.Forms.Timer):
private Timer timer = new Timer();
And set it up
timer.Tick += OnTick;
timer.Interval = int1 * 60000;
...
private void OnTick(object o, EventArgs e)
{
Console.Beep();
}
In your buttonclick you are now able to start and stop the timer:
timer.Start();
or
timer.Stop();
I would use a timer in this case, the reason why you can't close the form is because you are calling a sleep on the form thread from what I understand. Calling a sleep on the form thread will give the impression the app has crashed.
Here is a quick sample code I built in c#, it will beep the console at the time given. I hope it helps.
private void button1_Click(object sender, EventArgs e)
{
timer1.Tick += new EventHandler(timer_dosomething);
timer1.Interval = 60000;
timer1.Enabled = true;
timer1.Start();
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
}
void timer_dosomething(object sender, EventArgs e)
{
Console.Beep();
}

Working with a timer to show the label for some time

I am working on Windows Forms application. I have a windows form in which a label is set visible to false by default. I want to set property visible to true for 10 seconds and then after to false. I have dragged the timer control and set the interval to 1000 miliseconds, that is, 1 second, and I have written the code in form load event:
timer1.Start();
if (timer1.Interval == 5000)
{
timer1.Stop();
}
But it is not setting the label visible to false. Why?
In which event do I have to fire this code so that when the timer starts and when will it be 5 seconds and then the label will be set to false? Is that possible in C#?
Check the below code.
private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 10000;
timer1.Tick += new System.EventHandler(this.timer1_Tick);
label1.Visible = true;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop(); //If timer is not stopped, timer1_Tick event will be called for every 10 seconds
label1.Visible = false;
}
There is only one event for this timer -> tick which must be handled
timer1.Interval = 5000;
timer1.Tick += new EventHandler(timer1_Tick);
label1.Visible = true;
timer1.Start();
private void timer1_Tick(object sender, EventArgs e)
{
label1.Visible = false;
}
If you are using Windows Forms, by double clicking on the timer you should get this function in the code behind:
private void timer1_Tick(object sender, EventArgs e)
Try changing the label visibility in this function, and it should work.
Used this statement:
Label1.Visible = false
I think there is a problem with the attribute of Label1.

how to use timer effectively in c#

I have to show one form for about 5 sec and then I have to close that form and then show some other form once the new form is shown the timer has to stop.
I have difficulty in doing this.
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
Form5 f5 = new Form5();
f5.Show();
f5.label7.Text = label6.Text;
MyTimer.Interval = 5000; // 0.5 mins
MyTimer.Tick += new EventHandler(MyTimer_Tick);
MyTimer.Start();
}
private void MyTimer_Tick(object sender, EventArgs e)
{
MessageBox.Show("All The Best for Your Test and Your Time Starts Now.");
Form6 f6 = new Form6();
f6.Show();
MyTimer.Enabled = false;
Form5 f5 = new Form5();
f5.Hide();
}
try this code
Form5 f5 = new Form5();
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
f5.Show();
f5.label7.Text = label6.Text;
MyTimer.Interval = 5000; // 0.5 mins
MyTimer.Tick += new EventHandler(MyTimer_Tick);
MyTimer.Start();
}
private void MyTimer_Tick(object sender, EventArgs e)
{
MessageBox.Show("All The Best for Your Test and Your Time Starts Now.");
Form6 f6 = new Form6();
f6.Show();
MyTimer.Enabled = false;
MyTimer.stop();
f5.Hide();
}
Pull the declaration of Form5 outside of the functions, so it is a field. As it stands, each function has a different instance of this class.
Form5 f5 = new Form5();
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
f5.Show();
f5.label7.Text = label6.Text;
MyTimer.Interval = 5000; // 0.5 mins
MyTimer.Tick += new EventHandler(MyTimer_Tick);
MyTimer.Start();
}
private void MyTimer_Tick(object sender, EventArgs e)
{
MessageBox.Show("All The Best for Your Test and Your Time Starts Now.");
Form6 f6 = new Form6();
f6.Show();
MyTimer.Enabled = false;
MyTimer.Stop();
f5.Hide();
}
Note: You really should rename your form classes and the variables - f6 is meaningless. Call it what it is.
try this
Form5 f5 = new Form5(); //declare form obj globally
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
f5.Show();
f5.label7.Text = label6.Text;
MyTimer.Interval = 5000; // 0.5 mins
MyTimer.Tick += new EventHandler(MyTimer_Tick);
MyTimer.Start();
}
private void MyTimer_Tick(object sender, EventArgs e)
{
MessageBox.Show("All The Best for Your Test and Your Time Starts Now.");
Form6 f6 = new Form6();
f6.Show();
MyTimer.Enabled = false;
f5.Hide();
}
I see several potential problems. First, you should setup your timer only once, perhaps at Form construction time, you don't need to set the interval and wire up an even handler every single time radioButton1's check state changes.
Inside of MyTimer_Tick, the first line should be calling MyTimer.Stop() (just call stop, you don't need to mess with Enabled, they do the same thing).
THEN you can display the MessageBox (which is modal and blocking), show Form6, hide f5, etc.
Think of MessageBox.Show() as a really long running call. It doesn't return until the message box is dismissed (it can easily take more than 5 seconds or any arbitrary amount of time). While the MessageBox is up, timer tick events are still queuing up (because the line that stops the timer hasn't been executed yet). It would be worth looking up the documentation for MessageBox.Show() and reading about what a modal dialog is and how its different from the alternative.
And try and clean up the names as other's have pointed out.
I think You're making it to difficult. If I understood You correctly...
Just add a timer to form5, set it's properties Enabled = true; and Interavl = 1000; (1000 miliseconds or 1 second). and just add timer tick event handler to your form5 timer like
private int _start = 0;
private int _seconds = 5;
private void timer1_Tick(object sender, EventArgs e)
{
_start++;
if(_start >= _seconds)
{
Close();
}
}
_start and _seconds should be initialized like form class private fields, or properties before event handler. This code works fine for me, and it closes form5 after 5 seconds it was shown. If you want to make this more flexible, for example if you want to set how many seconds form5 should be shown U can, for example, reload form5 constructor like ...
public Form5(int seconds)
{
InitializeComponent();
_seconds = seconds;
}
and in form1, when you create form5 pass number of seconds U want to show form5 as parameter:
Form5 f5 = new Form5(5);
also I think it would be better to create new instance of form 5 dirrectly in event handler
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
new Form5(10).Show(); // show form5 for 10 seconds
...
}
If U want to show some another more form after form5 close, just show it before form5 close in timer tick event handler:
private void timer1_Tick(object sender, EventArgs e)
{
_start++;
if(_start >= _seconds)
{
new Form2().Show();
Close();
}
}

Categories