How to create a timer on a new thread

80 Views Asked by At

I recently asked a question as to how I would get a vertical line to sweep from left to right across a Picturebox. There were shapes in the Picturebox and the vertical line had to indicate when it crossed one. I had an answer that worked great.

Private lineX As Integer = 0

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    lineX += 5

    If lineX > PictureBox1.Width Then
        lineX = 0
    End If

    PictureBox1.Invalidate()
End Sub

Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    e.Graphics.DrawLine(Pens.Black,
                        New Point(lineX, 0),
                        New Point(lineX, PictureBox1.Height))
End Sub

However, I find that when I move the mouse around in the Picturebox, the vertical line stops, starts or slows down. From looking online, I think that a timer on a different thread might be the answer.

Could someone suggest a solution to this?

1

There are 1 best solutions below

7
Olivier Jacot-Descombes On

You could increase the accuracy of the movement by taking into account the effectively elapsed time:

Private lineX As Integer = 0
Private lastDateTime As Date?

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    PictureBox1.Invalidate()
End Sub

Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    Dim now = Date.Now
    If lastDateTime.HasValue Then
        lineX += CInt(5 * (now - lastDateTime.Value).Milliseconds / Timer1.Interval)
    Else
        lineX += 5
    End If
    lastDateTime = now

    If lineX > PictureBox1.Width Then
        lineX = 0
    End If
    e.Graphics.DrawLine(Pens.Black,
                        New Point(lineX, 0),
                        New Point(lineX, PictureBox1.Height))
End Sub

Note that I moved the code changing the line position into the PictureBox1_Paint method to get the exact time at which the line is drawn.

Painting can be delayed after PictureBox1.Invalidate() and painting can also occur in other situations, e.g., when the window is resized or moved around etc.

Some calls to PictureBox1_Paint can even be dropped if the system is busy.

Even after these changes the movement will not be perfect. WinForms is just not the right system for gaming like things.