Amit Gabay
Amit Gabay

Reputation: 29

Run a code that takes y seconds every x seconds until a button is clicked - C#

I'm trying to build a windows form (in C#) that has 2 buttons- start and stop, it looks like that:

enter image description here

(clicking the start button makes the stop button appear and the start button disappear and vice versa).

When clicking the start button, I want my program to run a certain code every x seconds until the stop button is clicked.

My problem is the following: lets say running this certain code takes 30 seconds, I want those 30 seconds to count in my 60 seconds interval.

What my code does so far is: counting 60 sec, execute certain code, counting 60 sec, execute certain code, counting 60 seconds etc....

What I want it to do is: run certain code WHILE start counting the 60 seconds, finish the code, keep counting whatever time is left (in my example 30 seconds), run code again (keep counting!) and so on...

Also, my code doesn't stop right away when clicking the stop button, it runs the code 1-2 more times and then stops.

This iss my code so far (button 1- start, button 2- stop):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        static bool exitFlag = false;
        static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();

        public Form1()
        {
            InitializeComponent();
        }

        private void agTextBox1_Load(object sender, EventArgs e) {}

        private void Form1_Load(object sender, EventArgs e){}

        private void textBox1_TextChanged(object sender, EventArgs e){}

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Visible = false;
            button2.Visible = true;

            myTimer.Tick += new EventHandler(TimerEventProcessor);

            // Sets the timer interval to 60 seconds.
            myTimer.Interval = 60000;
            myTimer.Start();

            // Runs the timer, and raises the event.
            while (exitFlag == false)
            {
                // Processes all the events in the queue.
                Application.DoEvents();
            }

        }


        private void TimerEventProcessor(object sender, EventArgs e)
        {
            //do something that takes x<60 seconds

                myTimer.Stop();

                // checks whether to continue running the timer.
                if (!button1.Visible)
                {
                    // Restarts the timer and increments the counter.
                    myTimer.Enabled = true;
                }
                else
                {
                    // Stops the timer.
                    exitFlag = true;
            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
            button2.Visible = true;
            button1.Visible = true;
        }
    }
}

Upvotes: 0

Views: 438

Answers (1)

Heinzi
Heinzi

Reputation: 172390

What I want it to do is: run certain code WHILE start counting the 60 seconds, finish the code, keep counting whatever time is left (in my example 30 seconds), run code again (keep counting!) and so on...

This is the default behavior of Timer. Just get rid of all that additional logic you put into your code to change that:

private void TimerEventProcessor(object sender, EventArgs e)
{
    //do something that takes x<60 seconds
}

And then just start/stop your timer with your buttons:

private void myStartButton_Click(object sender, EventArgs e)
{
    myTimer.Start();

    // Do your additional visibility/invisibility stuff.
}

private void myStopButton_Click(object sender, EventArgs e)
{
    myTimer.Stop();

    // Do your additional visibility/invisibility stuff.
}

Configuration of your timer should be done in the constructor, since there's no need to attach/detach the event handler on start/stop:

public Form1()
{
    InitializeComponent();

    myTimer.Interval = 60000;
    myTimer.Tick += new EventHandler(TimerEventProcessor);
}

You won't need your exitFlag any more.

Upvotes: 3

Related Questions