Unable to stop Timer in C# - c#

Hi all I have used timer class to call an event after a minute here is my code
public partial class TimerScheduler : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
}
System.Timers.Timer _timer = new System.Timers.Timer(10000);
protected void Button1_Click(object sender, EventArgs e)
{
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Enabled = true;
}
protected void Button2_Click(object sender, EventArgs e)
{
_timer.Stop();
_timer.Enabled=false;
}
}
but as I click start button timer works fine and after every minute it gets called but as I try to stop it it does not work And the _timer_Elapsed events gets called after every 1 minute

Edit the code as below
public partial class TimerScheduler : System.Web.UI.Page
{
System.Timers.Timer _timer = new System.Timers.Timer(10000);
protected void Page_Load(object sender, EventArgs e)
{
_timer.Elapsed -= new ElapsedEventHandler(_timer_Elapsed); //to avoid multiple linking of event
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
_timer.Enabled = true;
}
protected void Button2_Click(object sender, EventArgs e)
{
_timer.Enabled=false;
}
}

You could easily make the timer fire only once by setting AutoReset = false. Then you'd have to restart the timer manually in the timer's event handler.
System.Timers.Timer _timer = new System.Timers.Timer(1000);
bool timerStarted = false;
protected void Button1_Click(object sender, EventArgs e)
{
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Enabled = true;
_timer.AutoReset = false;
timerStarted = true;
}
protected void Button2_Click(object sender, EventArgs e)
{
timerStarted = false;
_timer.Enabled=false;
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
_timer.Enabled = timerStarted;
}
Oh, and by the way: I don't know what you're trying to achieve, but an ASP.NET page is not something that runs for a longer time. The code is executed once on the server and the HTML is passed back to the client. So what you want may not work at all.

You just Subscribe to the ElapsedEvent outside the Button1_Click event handler and start the Timer in Button1_Click event handler.
System.Timers.Timer _timer = new System.Timers.Timer(10000);
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
protected void Button1_Click(object sender, EventArgs e)
{
_timer.Start();
}
protected void Button2_Click(object sender, EventArgs e)
{
_timer.Stop();
}

Related

What can i add so my progra waits for the answer?

I have a pair of com ports.one of them sends data and the other one reads data. I want it to send a command (p) automatically every five seconds and wait to get the answer and read it and the sends the command again. Now it just sends the command automatically every 5 seconds. I don't know what to add to wait for the answer...
private Timer _timer;
public Form1()
{
InitializeComponent();
_timer = new Timer();
_timer.Interval = 5000;
_timer.Tick += _timer_Tick;
}
private void _timer_Tick(object sender , EventArgs e)
{
SendData();
}
private void Form1_Load(object sender, EventArgs e)
{
btnSendData.PerformClick();
}
private void btnSendData_Click(object sender, EventArgs e)
{
if (!_timer.Enabled)
{
SendData();
_timer.Enabled = true;
}
else
{
_timer.Enabled = false;
}
}
private void SendData()
{
if (serialPort1.IsOpen)
{
dataOut = "P<CR>";
serialPort1.Write(dataOut);
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
dataIn = serialPort1.ReadExisting();
this.Invoke(new EventHandler(ShowData));
}
private void ShowData(object sender, EventArgs e)
{
tBoxDataIn.Text += dataIn;
}
I think this will be helpful:
async
await
Using async to create a task and then awaiting it is the way to go i think.

I want to load my main code every 5 seconds?

I have a windows form app that display restaurant orders. I want to load the code every 5 seconds to check if there is a new order to display.
I have a timer created in the form designer:
public void timer1_Tick(object sender, EventArgs e)
{
}
public void DisplayRestaurantOrder()
{
//Display restaurant order here
}
private void Form1_Load(object sender, EventArgs e)
{
DisplayRestaurantOrder();
timer1.Interval = 5000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (true)//check new order
{
DisplayRestaurantOrder();
}
}
1) Set the timer's Interval property to 5000 (milliseconds)
2) Create a method which loads the data e.g.
private void LoadOrders()
{
// ... do stuff here
}
3) In the timer's Tick event handler make a call to the load method, in this case LoadOrders:
public void timer1_Tick(object sender, EventArgs e)
{
LoadOrders();
}
4) In the Form.Load event do timer1.Start();, and maybe also a initial call to the load method, to make a Form.Load event handler just double click the form:
private void Form1_Load(object sender, EventArgs e)
{
//LoadOrders(); //this is the initial load call.
//timer1.Start();
}
as a result you should have something like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
LoadOrders();
timer1.Start();
}
public void timer1_Tick(object sender, EventArgs e)
{
LoadOrders();
}
private void LoadOrders()
{
// ... do stuff here
}
}
UPDATE (sins the OP wants to load what is in the constructor):
If what is needed to be loaded, is in the Form1 constructor then just move everything from in there to a new method and make a call to that method in both the timer1_Tick handler and in the constructor itself, e.g.:
public Form1()
{
//InitializeComponent();
Load();
}
//should be kept as to start the timer.
private void Form1_Load(object sender, EventArgs e)
{
timer1.Start();
}
public void timer1_Tick(object sender, EventArgs e)
{
Load();
}
private void Load()
{
//InitializeComponent(); //this shouldn't be called more than once as it can create duplicate objects, i.e. buttons, menu strips, etc.
// ... do other stuff here
}

Get value of TextBox if 1s elapsed after last change c#

how can I get the value of my textbox 1seconde after the last change .
I tried with Stopwatch and TimerStamp but I just get the time between two change I don't know how to get the value of textbox 1 seconde after.
Thanks for help!
Edit:
Stopwatch TimerBetweenWrite = new Stopwatch();
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TimerBetweenWrite.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = TimerBetweenWrite.Elapsed;
if (Search.Text != null && ts.Seconds >= 1)
{
//doing my stuff
}
TimerBetweenWrite.Restart();
}
But this don't work like I want because we need to change the TextBox 1 seconde after last change. I want run a function 1 seconde after the last change of the TextBox but the user can continue to change the TextBox.
Final Edit:
That the code which work Thank's all for help!
public partial class ViewerPage : Page
{
System.Timers.Timer myTimer = new System.Timers.Timer(1000);
public ViewerPage()
{
InitializeComponent();
myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
myTimer.Stop(); //Reset timer
myTimer.Start(); //Restart it
}
private void myTimer_Elapsed(Object sender, ElapsedEventArgs e)
{
ThreadContext.InvokeOnUiThread(
delegate()
{
// Doing My Stuff
myTimer.Stop();
});
}
}
public static class ThreadContext
{
public static void InvokeOnUiThread(Action action)
{
if (Application.Current.Dispatcher.CheckAccess())
{
action();
}
else
{
Application.Current.Dispatcher.Invoke(action);
}
}
public static void BeginInvokeOnUiThread(Action action)
{
if (Application.Current.Dispatcher.CheckAccess())
{
action();
}
else
{
Application.Current.Dispatcher.BeginInvoke(action);
}
}
}
Timer myTimer = new Timer(1000);
myTimer.Elapsed += myTimer_Elapsed;
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
myTimer.Stop(); //Reset timer
myTimer.Start(); //Restart it
}
private void myTimer_Elapsed(Object sender, ElapsedEventArgs e)
{
//Do your stuff
}
Explanation: Each time the text changes, the timer gets reset and started again. It will only tick if it's enabled (aka not stopped by the TextChanged event) for a second.
If you want it to tick only once and then stop, set the AutoReset property to true.
You could inherit from TextBox and raise your own StableTextChanged event. The new control will appear at the top of your ToolBox:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void textBoxEx1_StableTextChanged(object sender, EventArgs e)
{
label1.Text = ((TextBoxEx)sender).Text;
}
}
public class TextBoxEx : TextBox
{
public event dlgStableTextChanged StableTextChanged;
public delegate void dlgStableTextChanged(object sender, EventArgs e);
private System.Windows.Forms.Timer tmr;
public TextBoxEx()
{
tmr = new System.Windows.Forms.Timer();
tmr.Interval = 1000;
tmr.Tick += Tmr_Tick;
this.TextChanged += TextBoxEx_TextChanged;
}
private void Tmr_Tick(object sender, EventArgs e)
{
tmr.Stop();
if (this.StableTextChanged != null)
{
this.StableTextChanged(this, new EventArgs());
}
}
private void TextBoxEx_TextChanged(object sender, EventArgs e)
{
tmr.Stop();
tmr.Start();
}
}

C# Panel Visibility on mouse Enter/Leave

Please note I'm trying to do the following, when I hover the mouse on a button I want the panel to be visible, when the mouse leaves the button or panel, the panel should not be visible. Below you can see the code I have, but the panel it's not staying visible.
private void FormMain()
{
buttonMenu.MouseEnter += new EventHandler(buttonMenu_MouseEnter); //open panel
buttonMenu.MouseLeave += new EventHandler(buttonMenu_MouseLeave);
panelMenu.MouseEnter += new EventHandler(panelMenu_MouseEnter);
panelMenu.MouseLeave += new EventHandler(panelMenu_MouseLeave);
mbB1.MouseEnter += new EventHandler(mbB1_MouseEnter);//button in panel
mbB2.MouseEnter += new EventHandler(mbB2_MouseEnter);//button in panel
}
private void buttonMenu_MouseEnter(object sender, EventArgs e)
{
this.panelMenu.Visible = true;
}
private void buttonMenu_MouseLeave(object sender, EventArgs e)
{
this.panelMenu.Visible = false;
}
private void panelMenu_MouseEnter(object sender, EventArgs e)
{
this.panelMenu.Visible = true;
}
private void panelMenu_MouseLeave(object sender, EventArgs e)
{
this.panelMenu.Visible = false;
}
private void mbB1_MouseEnter(object sender, EventArgs e)
{
this.panelMenu.Visible = true;
}
private void mbB2_MouseEnter(object sender, EventArgs e)
{
this.panelMenu.Visible = true;
}
One solution that came to my mind is using a short timer. You may further optimize it to cut down on LoC, but it works. You may also lower the timer's delay, but 100ms is what I think would be a safe one.
On a side note, I don't think this is a good design. If you want this kind of behaviour, you should either use a ContextMenuStrip or a Click event on the button, and a hide event on panelMenu.MouseLeave. Still, if it's what you really need, this is how I solved it:
public partial class Form1 : Form
{
private bool mouseInPanel;
private Timer hideTimer;
public Form1()
{
InitializeComponent();
buttonMenu.MouseEnter += new EventHandler(button_MouseEnter);
buttonMenu.MouseLeave += new EventHandler(button_MouseLeave);
mbB1.MouseEnter += panelButton_MouseEnter;
mbB2.MouseEnter += panelButton_MouseEnter;
panelMenu.MouseEnter += new EventHandler(panelMenu_MouseEnter);
panelMenu.MouseLeave += new EventHandler(panelMenu_MouseLeave);
hideTimer = new Timer {Interval = 100};
hideTimer.Tick += hidePanel;
}
private void button_MouseEnter(object sender, EventArgs e)
{
this.panelMenu.Visible = true;
}
private void button_MouseLeave(object sender, EventArgs e)
{
hideTimer.Start();
}
private void panelMenu_MouseEnter(object sender, EventArgs e)
{
mouseInPanel = true;
this.panelMenu.Visible = true;
}
private void panelMenu_MouseLeave(object sender, EventArgs e)
{
mouseInPanel = false;
hideTimer.Start();
}
private void panelButton_MouseEnter(object sender, EventArgs e)
{
mouseInPanel = true;
this.panelMenu.Visible = true;
}
private void hidePanel(object sender, EventArgs e)
{
hideTimer.Stop();
if (!mouseInPanel) this.panelMenu.Visible = false;
}
}
What I figured is your mouse actions needed a little bit of a delay, else the panel (along with your buttons mbB1 and mbB2) gets hidden before those buttons' actions could be triggered.
This is because by entering the panel buttons you leave the panel, and it disappears (along with it's capability to receive mouse actions) right before mbB1/mbB2's action can trigger.

MouseDown Event and Progress Bar

I would like to have a progress bar, where the value of the bar would rise if the button was being pressed down(MouseDown Event), the bar needs to rise simultaneousely.
Any ideas? I tried with a timer but this is all I have currently
private void button1_Click(object sender, EventArgs e)
{
progressBar1.PerformStep();
progressBar1.UseWaitCursor = true;
}
private void button2_Click(object sender, EventArgs e)
{
progressBar1.Value = 0;
}
public void button1_MouseDown(object sender, MouseEventArgs e)
{
timer1.Start();
}
public void button1_MouseUp(object sender, MouseEventArgs e)
{
timer1.Stop();
}
private void timer1_Tick(object sender, EventArgs e)
{
}
It should look like this:
void timer_Tick(object sender, EventArgs e) {
progressBar1.PerformStep();
}
void button1_MouseDown(object sender, MouseEventArgs e) {
timer.Start();
}
void button1_MouseUp(object sender, MouseEventArgs e) {
timer.Stop();
}
The following program will update the progress bar each 20 ms the mouse is held down and get 10 100% after 2 seconds
public partial class Form1 : Form
{
private Timer pbTimer;
private int pbProgress = 0;
public Form1()
{
InitializeComponent();
pbTimer = new Timer();
pbTimer.Tick += new EventHandler(ProgressUpdate);
pbTimer.Interval = 20;
this.MouseDown += Form1_MouseDown;
this.MouseUp += Form1_MouseUp;
}
private void ProgressUpdate(object sender, EventArgs e)
{
if (pbProgress < 100)
{
progressBar1.Value = ++pbProgress;
}
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
pbTimer.Start();
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
pbTimer.Stop();
progressBar1.Value = 0;
pbProgress = 0;
}

Categories