locked
Timer interval influences start time only? How does it work? RRS feed

  • Question

  • Hey, I was using the timer to make a panel slide down the entirety of the form and for some reason I can't get it to tick slower and it makes me wonder how the timer really works. Does it replay the portion of timer code on some frequency? Because as I increased the interval time, all that I noticed was that the panel just took longer to show up rather than slow down. What am I missing?

    I believe it might be because of the nesting I am doing with this code (It just runs off a button click event:

        Private Sub Timer_FormChange_Tick(sender As Object, e As EventArgs) Handles Timer_FormChange.Tick
            While Panel_Form2.Top < 0
                Panel_Form2.Top += 1
            End While
        End Sub

    - Faizan


    Wednesday, July 2, 2014 5:26 AM

Answers

  • You should be using an if statement not a loop. The timer is the repeater. If you want the panel to move faster and the timer interval is already down to 1 then Panel_Form2.Top += 2 or Panel_Form2.Top += 5, whatever.

    If Panel_Form2.Top < 0 Then

    Panel_Form2.Top += 1

    End If


    La vida loca


    Wednesday, July 2, 2014 6:03 AM

All replies

  • You should be using an if statement not a loop. The timer is the repeater. If you want the panel to move faster and the timer interval is already down to 1 then Panel_Form2.Top += 2 or Panel_Form2.Top += 5, whatever.

    If Panel_Form2.Top < 0 Then

    Panel_Form2.Top += 1

    End If


    La vida loca


    Wednesday, July 2, 2014 6:03 AM
  • You have strange code, 

    While Panel_Form2.Top < 0        Panel_Form2.Top +=1

    End While


    So this code will be only done once 

    For others if you use a timer and there is a change that the process takes more time then the interval. Stop the timer in the top of the method which handles the timer tick and start it again at the bottom.

    Be aware, screen handling even moving one pixel takes mostly more time then many calculations.


    Success
    Cor


    Wednesday, July 2, 2014 6:04 AM
  • You should be using an if statement not a loop. The timer is the repeater. If you want the panel to move faster and the timer interval is already down to 1 then Panel_Form2.Top += 2 or Panel_Form2.Top += 5, whatever.

    If Panel_Form2.Top < 0 Then

    Panel_Form2.Top += 1

    End If


    La vida loca


    Ok, the control structure has been fixed but I still need more speed for the panel to come down, is there no other way? Because by setting a high counting value the movement becomes chunky and not smooth. The panel still takes about 1.5 seconds to come down, which I need in about half of a second but not straight away.
    This is what I have, if it helps:

        Private Sub T_CircularPBar_Tick(sender As Object, e As EventArgs) Handles T_CircularPBar.Tick
            If CircularProgress1.Value <> 100 Then
                CircularProgress1.Value += 1
            Else
                Timer_FormChange.Enabled = True
                Timer_FormChange.Start()
    
            End If
        End Sub
    
        Private Sub SplashScreen_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Panel_Form2.Top = -410
        End Sub
    
        Private Sub Timer_FormChange_Tick(sender As Object, e As EventArgs) Handles Timer_FormChange.Tick
            If Panel_Form2.Top < 0 Then
                Panel_Form2.Top += 10
                PictureBox1.Refresh()
            End If
        End Sub



    Wednesday, July 2, 2014 7:14 AM
  • You have strange code, 

    While Panel_Form2.Top < 0        Panel_Form2.Top +=1

    End While


    So this code will be only done once 

    For others if you use a timer and there is a change that the process takes more time then the interval. Stop the timer in the top of the method which handles the timer tick and start it again at the bottom.

    Be aware, screen handling even moving one pixel takes mostly more time then many calculations.


    Success
    Cor


    I'm sorry, I don't quite understand what you mean by stopping and starting the timer. Do you mean stopping and starting in the timer tick event? If so, could you elaborate a bit on that, I'm not with you; how would that help? Please correct me if I have misunderstood you.
    Wednesday, July 2, 2014 7:15 AM
  • You have strange code, 

    While Panel_Form2.Top < 0        Panel_Form2.Top +=1

    End While


    So this code will be only done once 

    For others if you use a timer and there is a change that the process takes more time then the interval. Stop the timer in the top of the method which handles the timer tick and start it again at the bottom.

    Be aware, screen handling even moving one pixel takes mostly more time then many calculations.


    Success
    Cor


    I'm sorry, I don't quite understand what you mean by stopping and starting the timer. Do you mean stopping and starting in the timer tick event? If so, could you elaborate a bit on that, I'm not with you; how would that help? Please correct me if I have misunderstood you.

    Instead of the

    While

    End While

    try using the

    Do While

    Loop

    • Proposed as answer by John Ap Wednesday, July 2, 2014 10:20 AM
    • Unproposed as answer by John Ap Wednesday, July 2, 2014 10:20 AM
    Wednesday, July 2, 2014 10:20 AM
  • Ok, the control structure has been fixed but I still need more speed for the panel to come down, is there no other way? Because by setting a high counting value the movement becomes chunky and not smooth. The panel still takes about 1.5 seconds to come down, which I need in about half of a second but not straight away.

    This is what I have, if it helps:

        Private Sub T_CircularPBar_Tick(sender As Object, e As EventArgs) Handles T_CircularPBar.Tick
            If CircularProgress1.Value <> 100 Then
                CircularProgress1.Value += 1
            Else
                Timer_FormChange.Enabled = True
                Timer_FormChange.Start()
    
            End If
        End Sub
    
        Private Sub SplashScreen_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Panel_Form2.Top = -410
        End Sub
    
        Private Sub Timer_FormChange_Tick(sender As Object, e As EventArgs) Handles Timer_FormChange.Tick
            If Panel_Form2.Top < 0 Then
                Panel_Form2.Top += 10
                PictureBox1.Refresh()
            End If
        End Sub



     What is your Timers Interval set to? If that is set to the lowest possible such as 1 or 10 then you will need to increase the value that the panel is moved from (+= 10) to a higher number. There is no way to make it go any faster other than that.   :)

    If you say it can`t be done then i`ll try it

    Wednesday, July 2, 2014 10:42 AM
  • This is so simple, are you a programmer or even one who tries to become that, try it yourself. This is so basic.

    Private Sub Timer_FormChange_Tick(sender As Object, e As EventArgs) Handles Timer_FormChange.Tick
           timerFormChange.Stop
                Panel_Form2.Top += 10
            timerFormChange.Start
            
        End Sub


    Success
    Cor

    Wednesday, July 2, 2014 10:48 AM
  • This is so simple, are you a programmer or even one who tries to become that, try it yourself. This is so basic.


    This type of response is really unnecessary, and leaving aside the uncouth tone of your post your "solution" doesn't even help the OP.  He stated in his post that he understood what you meant but not how it would help move his panel faster - a sentiment I share.

    OP - WinForms isn't always the greatest when it comes to smooth animation of controls, so your choices are essentially to increase the pixel step that the panel moves by for each tick, or switch to WPF.  Keep in mind also that the timer's interval is usually affected by other factors and is rarely accurate, so if you want it to take a guaranteed precise 1 second to slide into view on every system this runs on, the timer is unlikely to be your friend here.

    Wednesday, July 2, 2014 12:45 PM
  • I don't see the problem? The little jerkiness is in the animated gif.

    Public Class Form2
        Private WithEvents Timer1 As New System.Windows.Forms.Timer With {.Interval = 20, .Enabled = True}
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            Static counterinc As Integer = 2
            If RadioButton1.Checked Then counterinc = Math.Sign(counterinc) * 2 Else counterinc = Math.Sign(counterinc) * 20
    
            If Panel1.Top > Me.ClientSize.Height Then counterinc = -counterinc
            If Panel1.Top < -Panel1.Height Then counterinc = -counterinc
    
            Panel1.Top = Panel1.Top + counterinc
    
        End Sub
    End Class

    Wednesday, July 2, 2014 1:23 PM
  • This is so simple, are you a programmer or even one who tries to become that, try it yourself. This is so basic.


    This type of response is really unnecessary, and leaving aside the uncouth tone of your post your "solution" doesn't even help the OP.  He stated in his post that he understood what you meant but not how it would help move his panel faster - a sentiment I share.

    OP - WinForms isn't always the greatest when it comes to smooth animation of controls, so your choices are essentially to increase the pixel step that the panel moves by for each tick, or switch to WPF.  Keep in mind also that the timer's interval is usually affected by other factors and is rarely accurate, so if you want it to take a guaranteed precise 1 second to slide into view on every system this runs on, the timer is unlikely to be your friend here.

    May I know what is the purpose of this message beside to offend me?

    Your message is a good sample of populism. You quote a part and left the part where I gave code out of your quote.

    http://en.wikipedia.org/wiki/Populism

     


    Success
    Cor



    Wednesday, July 2, 2014 2:48 PM
  • One important thing to keep in mind is that the resolution of the Forms.Timer control is limited to something like 56 milliseconds; any value lower than that won't take effect (you can set the timer to 10, but it will still only raise it's event every 50ish ms).

    You can use a Threading Timer to get roughly 15ms resolution (though its a little trickier to use due to cross-threading).

    It certainly takes a balance of timer interval and move distance to achieve the desired speed with as smooth an effect as possible, which is why timers are only good for simplistic animations or when accuracy isn't important.

    For the best control and accuracy it is probably better to run your own loop on a background thread rather than relying on a timer.  If you keep track of how long your loop takes to execute, then you can use that value to calculate movement in pixels-per-second and achieve fairly accurate motion at any reasonable speed.

    So the first issue has been well addressed - you were combining a looping solution with a timer solution and only want one or the other.  But if you still have an issue of getting the correct animation speed (and achieving a smooth result) then you may want to avoid the timer altogether.

    Here's a very rudimentary example:

    Public Class Form1
        Private Panel1 As New Panel With {.Size = New Size(100, 50), .BackColor = Color.CornflowerBlue, .Top = -51}
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.Size = New Size(800, 600)
            Me.CenterToScreen()
            Me.Controls.Add(Panel1)
            Task.Run(AddressOf SlidePanel)
        End Sub
    
        Private Sub SlidePanel()
            Dim sw As New Stopwatch
            Dim finished As Boolean
            Dim panelTop As Double = -50.0!
            Do While Not finished
                sw.Stop()
                panelTop += 200 * sw.Elapsed.TotalSeconds 'move 200 pixels per second
                sw.Restart()
                Invoke(Sub()
                           If Panel1.Bottom < Me.ClientRectangle.Bottom Then
                               Panel1.Top = panelTop
                           Else
                               finished = True
                           End If
                       End Sub)
            Loop
        End Sub
    End Class
    


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, July 2, 2014 3:08 PM
  • I don't see the problem? The little jerkiness is in the animated gif.

    That's because it's deceptive... 20 pixels is probably on the verge of what you can get away with.  Try doubling or tripling the speed though (on a larger form) and see how it looks.

    As stated, you can often strike a balance between movement distance and timer interval which will result in an acceptable animation under certain conditions.  You just have to work around that ~15-25 fps that it takes for the human brain to interpret motion.  The timer is already likely putting you in the middle of that threshold (you are probably getting like 20-22 fps) so you can't move the object very far before the human eye will notice gaps in the motion (anything below 25 could start to break the illusion for some viewers, and I believe that below 15 everyone will see the individual frames).


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, July 2, 2014 3:30 PM
  • Reed,

    I won't nitpick on your solution while I can. That is not the purpose of these forum. The OP can try it and decide it himself.

    But just a simple advice to you outside of this forum thread. Take once a slight study of the behaviour of the human eyes and their possibility of transferring data to the brain. 

    You will see that a refresh rate of 56 milliseconds is senseless to make moving panels really visible for the brains of humans. 

    Those who make the technical user interfaces are no fools, they use that knowledge. A refresh rate for a very good video for instance is  around 33 milliseconds. A gif is seldom quicker then 100 milliseconds a frame.

    Therefore moving a panel smooth up and down does not need that speed. The human brain does not recognise it, it is just itself correcting the movement automatically.


     


    Success
    Cor



    Wednesday, July 2, 2014 3:34 PM
  • Cor, as Quanta said, the code you provided in that example does nothing to address the issue; it will not make the panel move faster with any better result.

    The portion of text that was directly quoted was the part in question - the tone is hostile when read by a native English speaker (even if you didn't intend hostility, it is certainly there).  While the idea you were trying to get across is indeed simple, the phrasing of your English can make it hard to understand, so what was a simple concept becomes confusing.  It isn't fair to blame that confusion on the person who is trying to interpret your words.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, July 2, 2014 3:44 PM
  • By all means, nit-pick away.

    A gif at 100 ms/frame looks like a flip-book; it does not pass for "smooth" animation.  The limit for "smooth" is around 25 fps.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, July 2, 2014 3:47 PM
  • I don't see the problem? The little jerkiness is in the animated gif.

    That's because it's deceptive... 20 pixels is probably on the verge of what you can get away with.  Try doubling or tripling the speed though (on a larger form) and see how it looks.

    As stated, you can often strike a balance between movement distance and timer interval which will result in an acceptable animation under certain conditions.  You just have to work around that ~15-25 fps that it takes for the human brain to interpret motion.  The timer is already likely putting you in the middle of that threshold (you are probably getting like 20-22 fps) so you can't move the object very far before the human eye will notice gaps in the motion (anything below 25 could start to break the illusion for some viewers, and I believe that below 15 everyone will see the individual frames).


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Yes I understand. I just gave an example for talking purposes. Something to continue the conversation with. I am not sure if the OP wants it faster, slower etc. So maybe they can start with this example and then tell us how they would change it, faster, slower, not even close.

    Wednesday, July 2, 2014 3:48 PM
  • Cor, as Quanta said, the code you provided in that example does nothing to address the issue; it will not make the panel move faster with any better result.

    The portion of text that was directly quoted was the part in question - the tone is hostile when read by a native English speaker (even if you didn't intend hostility, it is certainly there).  While the idea you were trying to get across is indeed simple, the phrasing of your English can make it hard to understand, so what was a simple concept becomes confusing.  It isn't fair to blame that confusion on the person who is trying to interpret your words.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    In my experience it did. If a timer is faster then the UI can handle it, there is thrown a new event and the timer get hooked up.

    (Short written it is diner time here)

    Why should an OP not try given things? Seems to me a wrong use of forums. For that you can call Microsoft for paid help.

     


    Success
    Cor

    Wednesday, July 2, 2014 3:50 PM
  • In my experience it did. If a timer is faster then the UI can handle it, there is thrown a new event and the timer get hooked up.


    Cor

    Agreed; however, I find it hard to imagine that this:

        Private Sub Timer_FormChange_Tick(sender As Object, e As EventArgs) Handles Timer_FormChange.Tick
            If Panel_Form2.Top < 0 Then
                Panel_Form2.Top += 10
                PictureBox1.Refresh()
            End If
        End Sub

    Would take more than 50ms to execute...


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, July 2, 2014 3:57 PM
  • In my experience it did. If a timer is faster then the UI can handle it, there is thrown a new event and the timer get hooked up.


    Cor

    Agreed; however, I find it hard to imagine that this:

        Private Sub Timer_FormChange_Tick(sender As Object, e As EventArgs) Handles Timer_FormChange.Tick
            If Panel_Form2.Top < 0 Then
                Panel_Form2.Top += 10
                PictureBox1.Refresh()
            End If
        End Sub

    Would take more than 50ms to execute...


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Like I wrote in my first reply to the OP, that code will only execute once in a timer or not. (I now see it is never)


    Success
    Cor


    Wednesday, July 2, 2014 4:43 PM
  • I meant the correct implementation of what this code was intended to do.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, July 2, 2014 4:56 PM
  • Ok, the control structure has been fixed but I still need more speed for the panel to come down, is there no other way? Because by setting a high counting value the movement becomes chunky and not smooth. The panel still takes about 1.5 seconds to come down, which I need in about half of a second but not straight away.
    This is what I have, if it helps:

        Private Sub T_CircularPBar_Tick(sender As Object, e As EventArgs) Handles T_CircularPBar.Tick
            If CircularProgress1.Value <> 100 Then
                CircularProgress1.Value += 1
            Else
                Timer_FormChange.Enabled = True
                Timer_FormChange.Start()
    
            End If
        End Sub
    
        Private Sub SplashScreen_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Panel_Form2.Top = -410
        End Sub
    
        Private Sub Timer_FormChange_Tick(sender As Object, e As EventArgs) Handles Timer_FormChange.Tick
            If Panel_Form2.Top < 0 Then
                Panel_Form2.Top += 10
                PictureBox1.Refresh()
            End If
        End Sub



    Where is the picturebox located and why does it need to be refreshed?


    La vida loca

    Wednesday, July 2, 2014 5:08 PM
  • I can't replicate a jerky panel movement. If I could then I was going to use a double buffered panel class to created a double buffered panel to see if that corrected the issue.

    Also is your Form set to double buffered? Perhaps redrawing it's controls is not happening fast enough.

    The Panel is 200 x 200. The initial 1500 millisecond delay provides about a 1.5 second delay after the timer is started before the delay is set to 1 millisecond and the panel starts to move.

    Option Strict On
    
    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.CenterToScreen()
            Timer1.Interval = 1500
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Panel1.Top = -200
            Timer1.Interval = 1500
            LocX = CInt((PictureBox1.Width / 2) - 1)
            LocY = CInt((PictureBox1.Height / 2) - 1)
            EllipseWidth = 1
            EllipseHeight = 1
            Button1.Enabled = False
            Button1.BackColor = Color.OrangeRed
            Timer1.Start()
        End Sub
    
        Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
            e.Graphics.FillEllipse(Brushes.Red, LocX, LocY, EllipseWidth, EllipseHeight)
        End Sub
    
        Dim LocX As Integer = 0
        Dim LocY As Integer = 0
        Dim EllipseWidth As Integer = 1
        Dim EllipseHeight As Integer = 1
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            If Timer1.Interval = 1 Then
                LocX -= 10
                LocY -= 10
                EllipseWidth += 20
                EllipseHeight += 20
                If Panel1.Top < 0 Then
                    Panel1.Top += 20
                    PictureBox1.Refresh()
                End If
                If Panel1.Top >= 0 Then
                    Timer1.Stop()
                    Button1.Enabled = True
                    Button1.BackColor = Color.Lime
                End If
            Else
                Timer1.Interval = 1
            End If
    
        End Sub
    
    End Class


    La vida loca



    Wednesday, July 2, 2014 5:28 PM