Results 1 to 7 of 7

Thread: Need timer to function while keys are held down

  1. #1

    Thread Starter
    New Member
    Join Date
    Nov 2012
    Posts
    3

    Need timer to function while keys are held down

    I am a beginner programmer messing around with graphic programming in VB 2010...I control a graphic with arrow key presses. When I hold down the arrow key to move my character, the timer seems to pause. On the timer's tick event, it is simply set up to switch a label's text to each day of the week. Is there a way to keep the timer active even while a key is being held down?

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: Need timer to function while keys are held down

    The timer isn't pausing, what is happening is that the tick event never gets a chance to be handled because you are blocking it. That may not be so simple to solve. There may be an easy way, depending on what you are doing on the keypress. If there is a loop happening, then an Application.DoEvents would make the timer remain responsive. However, if you aren't handling the keydown events, then there probably isn't any suitable place to put the DoEvents.

    The alternative would be to use a System.Timers.Timer rather than Forms.Timer. The Timers.Timer raises the tick events on a different thread, so it won't be blocked. However, since it is on a different thread, you will have to use the Invoke method to be able to change controls, which are UI thread items. There are plenty of examples of that, though, so it shouldn't be too hard.
    My usual boring signature: Nothing

  3. #3

    Thread Starter
    New Member
    Join Date
    Nov 2012
    Posts
    3

    Re: Need timer to function while keys are held down

    Hey thanks a million for the prompt response...I just had to add Application.DoEvents when I draw my graphics.

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: Need timer to function while keys are held down

    You may want to go a bit further than that. It seems likely that the timing for a single iteration of whatever graphics loop you have is pretty quick. DoEvents is a rather costly method. Therefore, you might want to arrange it so that it is called only once every 10 iterations, or more.
    My usual boring signature: Nothing

  5. #5

    Thread Starter
    New Member
    Join Date
    Nov 2012
    Posts
    3

    Re: Need timer to function while keys are held down

    Hmmm...Like I said I am a newb Any chance you could elaborate a bit? How would I go about doing that?

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: Need timer to function while keys are held down

    It's mostly a philosophical issue. Some statements take longer to execute than others. If the performance is fine, then there isn't any great reason to make any changes. However, if the performance begins to slow down, then DoEvents is not your friend. That method can take a measurable amount of time. If you are doing something over and over, such as handling repeated key events, and you are calling DoEvents each time through, then that might end up costing you noticeably in performance. If that is the case, you might put an integer variable at form scope (outside any method). Every time through the code, increment that variable. When the variable > N, call DoEvents and set the variable back to 0. By doing that, DoEvents happens only once every ten iterations rather than every iteration.

    DoEvents suspends the activity and processes all pending messages, such as button clicks, timer ticks, and all like that. Therefore, all it really does is keeps the interface responsive. There isn't any reason for it to be called more often than once every 200 ms, or so, because nobody will perceive a delay of 1/5 of a second, so the UI can be unresponsive for that long without any harm. So, if your loop is taking 10 ms (which would be a really slow loop), then you could get away with calling DoEvents once every 20 iterations (N = 20 in the previous example) and the user wouldn't notice the difference.

    Of course, this is all just a matter of performance and perception. If the performance is fine, then you don't gain anything by doing this. If the performance is not as zippy as you would like, then doing something like this so that the DoEvents is called only once every N iterations, would be a good thing to do. N might be 10, 20, 100, or even more. Once you had it set up, you could try different values to see what you liked. The bigger N was, the less frequently that DoEvents is called, so the more time is spent on the graphics, but the less responsive the program is to events. The smaller N is, the more responsive the program is to events, but the more time is wasted checking for those infrequent events.
    My usual boring signature: Nothing

  7. #7
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Need timer to function while keys are held down

    Application.DoEvents Method . My opinion about the use of this is summarized in my signature.

    Shaggy suggested System.Timers.Timer. Here is an example of that. Something like this will resolve your issue without resorting to .DoEvents.

    Code:
        Dim WithEvents aTimer As New System.Timers.Timer()
    
        Private Sub Form1_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
            aTimer.AutoReset = True 'raise event every time 
            aTimer.Interval = 1000 'set the interval
            AddHandler aTimer.Elapsed, AddressOf aTimer_elapsed
            aTimer.Start() 'start the timer
            'aTimer.SynchronizingObject = Me 'see http://msdn.microsoft.com/en-us/library/system.timers.timer.synchronizingobject%28v=vs.100%29.aspx
        End Sub
    
        Dim aTimerLock As New Object
        Private Sub aTimer_elapsed(source As Object, e As Timers.ElapsedEventArgs)
            ' the Elapsed event is raised on a ThreadPool thread normally
            If Threading.Monitor.TryEnter(aTimerLock) Then 'guard against reentrant
                aTimerUI()
                Threading.Monitor.Exit(aTimerLock) 'release the lock
            End If
        End Sub
    
        Private Sub aTimerUI()
            If Me.InvokeRequired Then
                'yes
                Dim onUI As Action = AddressOf aTimerUI
                Me.Invoke(onUI)
            Else
                'no
                Label1.Text = DateTime.Now.ToLongTimeString
            End If
        End Sub
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width