0

The timer does not start without the EventHandler (timerIdle_Tick):

timerIdle.Tick += new EventHandler(timerIdle_Tick);

Follow the timer code after your indication:

class Timers
{
    public static System.Windows.Forms.Label lblIdle;
    public static Timer timerIdle = new Timer();
    public static int segundo = 0;

    // TIMER IDLE
    public static void timerIdleOn()
    {
        segundo = 300;
        timerIdle.Interval = 1000;
        timerIdle.Start();
    }
    public static void timerIdleOff()
    {
        timerIdle.Stop();
    }

    public static void timerIdle_Tick(object sender, EventArgs e)
    {
        segundo--;

        if (segundo == 0)
        {
            timerIdle.Stop();
            dgView.addLinha(2, "config_Teste", "TIMER ACABOU", 0);
        }
        else
            dgView.addLinha(2, "config_Teste", TimeSpan.FromSeconds(segundo).ToString(@"mm\:ss"), 0);
    }
}

It follows where the timer is started, I don't use buttons, just one temporarily to test methods, it won't exist afterwards.

namespace HC
{
    public partial class frm_console : Form
    {
        public frm_console()
        {
            InitializeComponent();
            dgView.DataConsole = this.DataConsol;           
            Timers.timerIdleOn();
        }
    }
}
  • 1
    Why are you disposing the timer while you need to use it again? See my **Side Note** in your previous question. –  Jul 16 '20 at 23:02
  • This line: `timerIdle.Tick += new EventHandler(timerIdle_Tick);` should only be called ONCE in your application, like from the Load() event of the Form. Otherwise, every time you stop and then start again, you're going to end up subscribing to that Tick() event multiple times and the Tick() event will fire more than you are expecting it to. This is assuming you don't `Dispose()` it and re-create it every time with the `new` keyword...but it doesn't look like there is a good reason to be doing that. – Idle_Mind Jul 16 '20 at 23:11
  • JQSOFT I tested your example, but it does not decrease the time as necessary, it increases. About Dispose (), I forgot to take it out when I put it here, it was commented. – Maurício Morhy Jul 16 '20 at 23:17
  • timerIdleReset() { timerIdleOff(); timerIdleOn(); } – Maurício Morhy Jul 17 '20 at 04:05

3 Answers3

1

With respect to this:

timerIdle.Stop();
timerIdle.Start();

The Timer object doesn't know anything about the time-keeping. It's just a mechanism that allows your timerIdle_Tick() method to be called at regular intervals. So, naturally simply stopping and starting the timer again is going to have no effect at all on the displayed time for the timer.

As with your previous question about this program, you still have not provided a Minimal, Complete, and Verifiable code example. So it's impossible to know for sure what would be needed.

But looking at the code you posted, it seems to me that you can simply assign a new value to your tempo variable, to start the count back at whatever time you want. E.g.:

timerIdle.Stop();
tempo = 300; // 300 seconds, or in other words, 5 minutes
timerIdle.Start();

For what it's worth, your code can be simplified. Well, ignoring for the moment that the "decrement a seconds counter on each tick" is simply the wrong way to implement this (as has been explained to you in your previous question), the body of your Tick handler method could look more like this and still do the same thing:

public static void timerIdle_Tick(object sender, EventArgs e)
{
    tempo--; // decrement first, then segundo and minuto already will be automatically decremented correctly

    // NOTE: it's not clear whether these are even used outside this method.
    // If not, just make them locals and do this computation only in the
    // "else" block below.
    minuto = tempo / 60; // will be 0 if tempo < 60
    segundo = tempo % 60; // will be tempo if tempo < 60

    if (tempo < 0)
    {
        timerIdle.Stop();

        // WARNING: this renders the timerIdle object invalid for future use.
        // If you try to restart the timer without creating a new one after this
        // statement executes, an exception will be thrown. If you intend to ever
        // reuse timerIdle, you should not dispose it here.
        timerIdle.Dispose();

        dgView.addLinha(2, "config_Teste", "TIMER ACABOU", 0);
    }
    else
    {
        // no need to recombine minuto and segundo back into tempo,
        // since tempo was already decremented to start with and
        // continues to have the right value here.

        string temp = string.Format($"{minuto:D2}:{segundo:D2}");
        lblIdle.Text = temp;
        dgView.addLinha(2, "config_Teste", temp, 0);
    }
}
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
1

This is more like what I'd expect to see. The Timer is being created and handled INSIDE the frm_console class. Note that all of the statics have been REMOVED:

public partial class frm_console : Form
{

    public int segundo = 300;
    public Timer timerIdle = new Timer();   
    
    public frm_console()
    {
        InitializeComponent();
        dgView.DataConsole = this.DataConsol;
        timerIdle.Interval = 1000; 
        timerIdle.Tick += new EventHandler(timerIdle_Tick);        
        timerIdle.Start();
    }
    
    private void btnReset_Click(object sender, EventArgs e)
    {
        segundo = 300; // reset to 5 minutes
        timerIdle.Start();
    }

    private void btnPauseResume_Click(object sender, EventArgs e)
    {
        if (timerIdle.Enabled)
        {
            timerIdle.Stop();
        }
        else if (segundo > 0)
        {
            timerIdle.Start();
        }
    }

    private void btnStop_Click(object sender, EventArgs e)
    {
        timerIdle.Stop();
    }   

    public void timerIdle_Tick(object sender, EventArgs e)
    {
        segundo--;
        
        if (segundo == 0)
        {
            timerIdle.Stop();
            dgView.addLinha(2, "config_Teste", "TIMER ACABOU", 0);
        }
        else
        {
            dgView.addLinha(2, "config_Teste", TimeSpan.FromSeconds(segundo).ToString(@"mm\:ss"), 0);
        }
    }
            
}

The methods beginning with "btn" are button click handlers, but they could be converted to regular methods. You should be able to understand what they're doing.

Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
  • He already [has](https://stackoverflow.com/a/62936194/10216583) this version. He said above it does't work. I don't know why. –  Jul 16 '20 at 23:27
  • 1
    @JQSOFT So he does!...I dont' see why it wouldn't work either. ;) – Idle_Mind Jul 16 '20 at 23:28
  • I tried as written here, but the timer does not start without ``timerIdle.Tick + = new EventHandler (timerIdle_Tick);``, and I can't restart the timer, I need you to go back to 5 minutes (300 seconds) by one method, sorry everyone for my ignorance, but something simple for you, is not simple for me. – Maurício Morhy Jul 17 '20 at 00:08
  • @MaurícioMorhy No problem buddy don't give up :). Now, What all these `static` modifiers in you code? Can you get rid of them? Keep the timer and its code in the Form. Can you do that for now? Also, where do you need to restart the Timer in your code? In a Button click for example? Or right after when the timer stops? –  Jul 17 '20 at 00:28
  • Show us more code from the form itself, dealing with the timer. Didn't notice the `static`s in there... that could potentially be part if the problem. – Idle_Mind Jul 17 '20 at 00:45
  • I use static because in fact it is the way I managed to make the system work, I don't even know the problem it can cause, but it is working. Last time I programmed it was 20 years ago with VB6, I started now with C #, everything is very new for me. I need to restart the Timer in a method, this method is in a separate file but with the same namespace as the form, however, in a different class. The system I'm creating has no buttons, it's all via methods. – Maurício Morhy Jul 17 '20 at 01:16
  • ``namespace HC { public partial class frm_console : Form { public frm_console() { InitializeComponent(); dgView.DataConsole = this.DataConsol; Timers.lblIdle = this.lblIdle; Timers.timerIdleOn(); } private void button1_Click(object sender, EventArgs e) { lblIdle.Visible = true; Timers.timerIdle.Enabled = !Timers.timerIdle.Enabled; } } }`` This button is only for testing methods, it will not exist in the future. – Maurício Morhy Jul 17 '20 at 01:20
  • @MaurícioMorhy No need to handle the Timer in different class `Timers`. Anyways, in the `button1_Click` event in the Form, set also `tempo = 300` again since it's value when the Timer stops is `0`. Hence you need to reassign it. –  Jul 17 '20 at 02:00
  • Also you can reassign it in the `Tick` event when you stop the timer. `if (tempo == 0) { timerIdle.Stop(); tempo = 300; dgView.addLinha(2, "config_Teste", "TIMER ACABOU", 0) }` AND don't dispose it. –  Jul 17 '20 at 02:12
  • I edited the post as it is here now after your suggestions, could you check again please? – Maurício Morhy Jul 17 '20 at 02:23
  • The idea is to restart the timer whenever necessary through methods, if it reaches the end the application has ended and will close, but before that I have to restart it several times. – Maurício Morhy Jul 17 '20 at 02:26
  • @MaurícioMorhy Which method that will reset and restart the timer? Make it quick please I have flight to catch before they close the Airport again. So I need to get ready. –  Jul 17 '20 at 03:43
  • timerIdleReset () {timerIdleOff (); timerIdleOn (); } – Maurício Morhy Jul 17 '20 at 04:09
0

Did you try this:

  timerIdle.Enabled = false;
  timerIdle.Enabled = true;
Math-O5
  • 365
  • 3
  • 8
  • 3
    There is zero difference between modifying the `Enabled` property and calling `Stop()` or `Start()`. This couldn't possible be useful to the author of the question in terms of addressing the specific problem they are asking about here. – Peter Duniho Jul 16 '20 at 23:06
  • No, but it was interesting, I even went and took a look, Start is one line of code.. Enabled = true; – LordWabbit May 04 '22 at 09:22