DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 7 of 7

Thread: Doevents causes 100% CPU load?!?

  1. #1
    Felix Haas Guest

    Doevents causes 100% CPU load?!?


    Hi all,

    for a window animation routine, I need to control the speed:

    dim start as single
    dim i%

    for i% = 1 to x

    [animation code, do step #xxxx]

    start=timer
    do
    doevents
    loop until timer-start>0.1 ' 1/10 sec per step

    next


    Problem: The taskmanager says 100% workload, even a simple

    do
    doevents
    loop

    causes 100% load! I thought that doevents tells windows that my thread doesn't
    have anything to do right now, therefore I expected to read 0% in the cpu
    monitor.

    What's wrong / How can I achieve 0% cpu load while idling? I don't think
    that the API call "sleep" will work for me as my thread is doing a lot of
    stuff in the background and it must not be blocked.

    Thanks for help!

    Felix


  2. #2
    Michael Shutt Guest

    Re: Doevents causes 100% CPU load?!?

    DoEvents just pauses the current thread of execution until all windows/ole
    messages waiting in the queue have been processed. If there are none
    pending, your code resumes immediately.

    I would suggest using a timer as the "engine" for processing.

    --
    Michael Shutt

    Please respond to newsgroup as I will not return direct emails.

    "Felix Haas" <felix@tiberiumsun.com> wrote in message
    news:3af2724a$1@news.devx.com...
    >
    > Hi all,
    >
    > for a window animation routine, I need to control the speed:
    >
    > dim start as single
    > dim i%
    >
    > for i% = 1 to x
    >
    > [animation code, do step #xxxx]
    >
    > start=timer
    > do
    > doevents
    > loop until timer-start>0.1 ' 1/10 sec per step
    >
    > next
    >
    >
    > Problem: The taskmanager says 100% workload, even a simple
    >
    > do
    > doevents
    > loop
    >
    > causes 100% load! I thought that doevents tells windows that my thread

    doesn't
    > have anything to do right now, therefore I expected to read 0% in the cpu
    > monitor.
    >
    > What's wrong / How can I achieve 0% cpu load while idling? I don't think
    > that the API call "sleep" will work for me as my thread is doing a lot of
    > stuff in the background and it must not be blocked.
    >
    > Thanks for help!
    >
    > Felix
    >




  3. #3
    Michael Shutt Guest

    Re: Doevents causes 100% CPU load?!?

    DoEvents just pauses the current thread of execution until all windows/ole
    messages waiting in the queue have been processed. If there are none
    pending, your code resumes immediately.

    I would suggest using a timer as the "engine" for processing.

    --
    Michael Shutt

    Please respond to newsgroup as I will not return direct emails.

    "Felix Haas" <felix@tiberiumsun.com> wrote in message
    news:3af2724a$1@news.devx.com...
    >
    > Hi all,
    >
    > for a window animation routine, I need to control the speed:
    >
    > dim start as single
    > dim i%
    >
    > for i% = 1 to x
    >
    > [animation code, do step #xxxx]
    >
    > start=timer
    > do
    > doevents
    > loop until timer-start>0.1 ' 1/10 sec per step
    >
    > next
    >
    >
    > Problem: The taskmanager says 100% workload, even a simple
    >
    > do
    > doevents
    > loop
    >
    > causes 100% load! I thought that doevents tells windows that my thread

    doesn't
    > have anything to do right now, therefore I expected to read 0% in the cpu
    > monitor.
    >
    > What's wrong / How can I achieve 0% cpu load while idling? I don't think
    > that the API call "sleep" will work for me as my thread is doing a lot of
    > stuff in the background and it must not be blocked.
    >
    > Thanks for help!
    >
    > Felix
    >




  4. #4
    Monte Hansen Guest

    Re: Doevents causes 100% CPU load?!?

    Try these. "Pause" is very CPU friendly, unlike DoEvents by itself. You will
    need to fish out the declares, however. Replace my ApiRaise with Err.Raise.

    +|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+
    Monte Hansen
    http://KillerVB.com
    +|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+

    Public Sub Pause(ByVal Milliseconds As Long, _
    Optional ByVal WakeMask As QueueStatusFlags = QS_ALLINPUT,
    _
    Optional lpAbort As Long)
    '===========================================================================
    ' Pause - CPU Friendly way to pause a Task.
    '===========================================================================

    Dim hEvent As Long

    ' Sanity check.
    If Milliseconds <= 0 Then Exit Sub

    ' Create a bogus event to wait on. It will never be siganaled.
    hEvent = CreateEvent(ByVal 0, 1, 0, vbNullString)
    If IsValidHandle(hEvent) Then
    ' Wait until timeout expires
    WaitOnEvent hEvent, Milliseconds, WakeMask, lpAbort:=lpAbort
    ' Destroy the event
    CloseHandle hEvent
    Else
    ApiRaise Err.LastDllError, Module, "Could not create event."
    End If

    End Sub

    Public Function WaitOnEvent(ByVal hEvent As Long, _
    Optional ByVal TimeoutValue As Long = 15000, _
    Optional ByVal WakeMask As QueueStatusFlags =
    QS_ALLINPUT, _
    Optional WaitValue As Long, _
    Optional ByVal lpAbort As Long) As Long

    ' Wait on the single event
    WaitOnEvent = WaitOnEvents(1, _
    VarPtr(hEvent), _
    False, _
    TimeoutValue, _
    WakeMask, _
    WaitValue, _
    lpAbort)

    End Function

    Public Function WaitOnEvents(ByVal nEvents As Long, _
    ByVal lpEvents As Long, _
    Optional ByVal WaitOnAll As Boolean = False, _
    Optional ByVal TimeoutValue As Long = 15000, _
    Optional ByVal WakeMask As QueueStatusFlags =
    QS_ALLINPUT, _
    Optional WaitValue As Long, _
    Optional ByVal lpAbort As Long) As Long

    Const INFINITE = &HFFFFFFFF ' Infinite timeout
    Const WAIT_FAILED = -1&
    Const WAIT_TIMEOUT = 258& ' Wait timed out
    Const WAIT_ABANDONED_0 = &H80&
    Const WAIT_OBJECT_0 = 0
    'onst WAIT_IO_COMPLETION = &HC0& ' MsgWaitForMultipleObjectsEx

    Dim EndTime As Long
    Dim TimeoutTicks As Long
    Dim AbortVal As Long

    ' Calculate time out value, if any supplied
    If TimeoutValue > 0 Then
    EndTime = timeGetTime() + TimeoutValue
    Else
    TimeoutTicks = INFINITE
    End If

    Do

    ' If an abort variable supplied...
    If lpAbort <> 0 Then
    ' Copy contents of abort variable to local variable
    CopyMemory ByVal VarPtr(AbortVal), ByVal lpAbort, 2
    ' Exit if the abort variable is set.
    If AbortVal <> 0 Then Exit Do
    End If

    ' Calculate # of milliseconds left before we must time out.
    If TimeoutValue > 0 Then
    TimeoutTicks = TickDiff(timeGetTime(), EndTime)
    End If

    ' Wait on the supplied event
    WaitValue = MsgWaitForMultipleObjects _
    (nEvents, ByVal lpEvents, Abs(WaitOnAll), TimeoutTicks,
    WakeMask)

    ' Process the result
    Select Case WaitValue
    Case WAIT_OBJECT_0 To (WAIT_OBJECT_0 + nEvents - 1), _
    WAIT_ABANDONED_0 To (WAIT_ABANDONED_0 + nEvents - 1)

    ' Return a one-based index identifying the event that signaled
    WaitOnEvents = WaitValue + 1
    Exit Do

    Case (WAIT_OBJECT_0 + nEvents)

    ' We need to process the msg queue. Refer to the SDK for more
    info.
    'WaitOnEvents = nEvents
    'Exit Do

    Case WAIT_TIMEOUT

    ' We've timed out. Exit function.
    Exit Do

    Case WAIT_FAILED

    ' There was an error. Handle probably invalid.
    ApiRaise Err.LastDllError, , "Wait event(s) failed."

    Case Else

    Debug.Assert 0

    End Select

    DoEvents

    Loop

    End Function


    "Felix Haas" <felix@tiberiumsun.com> wrote in message
    news:3af2724a$1@news.devx.com...
    >
    > Hi all,
    >
    > for a window animation routine, I need to control the speed:
    >
    > dim start as single
    > dim i%
    >
    > for i% = 1 to x
    >
    > [animation code, do step #xxxx]
    >
    > start=timer
    > do
    > doevents
    > loop until timer-start>0.1 ' 1/10 sec per step
    >
    > next
    >
    >
    > Problem: The taskmanager says 100% workload, even a simple
    >
    > do
    > doevents
    > loop
    >
    > causes 100% load! I thought that doevents tells windows that my thread

    doesn't
    > have anything to do right now, therefore I expected to read 0% in the cpu
    > monitor.
    >
    > What's wrong / How can I achieve 0% cpu load while idling? I don't think
    > that the API call "sleep" will work for me as my thread is doing a lot of
    > stuff in the background and it must not be blocked.
    >
    > Thanks for help!
    >
    > Felix
    >




  5. #5
    Monte Hansen Guest

    Re: Doevents causes 100% CPU load?!?

    Try these. "Pause" is very CPU friendly, unlike DoEvents by itself. You will
    need to fish out the declares, however. Replace my ApiRaise with Err.Raise.

    +|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+
    Monte Hansen
    http://KillerVB.com
    +|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+

    Public Sub Pause(ByVal Milliseconds As Long, _
    Optional ByVal WakeMask As QueueStatusFlags = QS_ALLINPUT,
    _
    Optional lpAbort As Long)
    '===========================================================================
    ' Pause - CPU Friendly way to pause a Task.
    '===========================================================================

    Dim hEvent As Long

    ' Sanity check.
    If Milliseconds <= 0 Then Exit Sub

    ' Create a bogus event to wait on. It will never be siganaled.
    hEvent = CreateEvent(ByVal 0, 1, 0, vbNullString)
    If IsValidHandle(hEvent) Then
    ' Wait until timeout expires
    WaitOnEvent hEvent, Milliseconds, WakeMask, lpAbort:=lpAbort
    ' Destroy the event
    CloseHandle hEvent
    Else
    ApiRaise Err.LastDllError, Module, "Could not create event."
    End If

    End Sub

    Public Function WaitOnEvent(ByVal hEvent As Long, _
    Optional ByVal TimeoutValue As Long = 15000, _
    Optional ByVal WakeMask As QueueStatusFlags =
    QS_ALLINPUT, _
    Optional WaitValue As Long, _
    Optional ByVal lpAbort As Long) As Long

    ' Wait on the single event
    WaitOnEvent = WaitOnEvents(1, _
    VarPtr(hEvent), _
    False, _
    TimeoutValue, _
    WakeMask, _
    WaitValue, _
    lpAbort)

    End Function

    Public Function WaitOnEvents(ByVal nEvents As Long, _
    ByVal lpEvents As Long, _
    Optional ByVal WaitOnAll As Boolean = False, _
    Optional ByVal TimeoutValue As Long = 15000, _
    Optional ByVal WakeMask As QueueStatusFlags =
    QS_ALLINPUT, _
    Optional WaitValue As Long, _
    Optional ByVal lpAbort As Long) As Long

    Const INFINITE = &HFFFFFFFF ' Infinite timeout
    Const WAIT_FAILED = -1&
    Const WAIT_TIMEOUT = 258& ' Wait timed out
    Const WAIT_ABANDONED_0 = &H80&
    Const WAIT_OBJECT_0 = 0
    'onst WAIT_IO_COMPLETION = &HC0& ' MsgWaitForMultipleObjectsEx

    Dim EndTime As Long
    Dim TimeoutTicks As Long
    Dim AbortVal As Long

    ' Calculate time out value, if any supplied
    If TimeoutValue > 0 Then
    EndTime = timeGetTime() + TimeoutValue
    Else
    TimeoutTicks = INFINITE
    End If

    Do

    ' If an abort variable supplied...
    If lpAbort <> 0 Then
    ' Copy contents of abort variable to local variable
    CopyMemory ByVal VarPtr(AbortVal), ByVal lpAbort, 2
    ' Exit if the abort variable is set.
    If AbortVal <> 0 Then Exit Do
    End If

    ' Calculate # of milliseconds left before we must time out.
    If TimeoutValue > 0 Then
    TimeoutTicks = TickDiff(timeGetTime(), EndTime)
    End If

    ' Wait on the supplied event
    WaitValue = MsgWaitForMultipleObjects _
    (nEvents, ByVal lpEvents, Abs(WaitOnAll), TimeoutTicks,
    WakeMask)

    ' Process the result
    Select Case WaitValue
    Case WAIT_OBJECT_0 To (WAIT_OBJECT_0 + nEvents - 1), _
    WAIT_ABANDONED_0 To (WAIT_ABANDONED_0 + nEvents - 1)

    ' Return a one-based index identifying the event that signaled
    WaitOnEvents = WaitValue + 1
    Exit Do

    Case (WAIT_OBJECT_0 + nEvents)

    ' We need to process the msg queue. Refer to the SDK for more
    info.
    'WaitOnEvents = nEvents
    'Exit Do

    Case WAIT_TIMEOUT

    ' We've timed out. Exit function.
    Exit Do

    Case WAIT_FAILED

    ' There was an error. Handle probably invalid.
    ApiRaise Err.LastDllError, , "Wait event(s) failed."

    Case Else

    Debug.Assert 0

    End Select

    DoEvents

    Loop

    End Function


    "Felix Haas" <felix@tiberiumsun.com> wrote in message
    news:3af2724a$1@news.devx.com...
    >
    > Hi all,
    >
    > for a window animation routine, I need to control the speed:
    >
    > dim start as single
    > dim i%
    >
    > for i% = 1 to x
    >
    > [animation code, do step #xxxx]
    >
    > start=timer
    > do
    > doevents
    > loop until timer-start>0.1 ' 1/10 sec per step
    >
    > next
    >
    >
    > Problem: The taskmanager says 100% workload, even a simple
    >
    > do
    > doevents
    > loop
    >
    > causes 100% load! I thought that doevents tells windows that my thread

    doesn't
    > have anything to do right now, therefore I expected to read 0% in the cpu
    > monitor.
    >
    > What's wrong / How can I achieve 0% cpu load while idling? I don't think
    > that the API call "sleep" will work for me as my thread is doing a lot of
    > stuff in the background and it must not be blocked.
    >
    > Thanks for help!
    >
    > Felix
    >




  6. #6
    Peter Young Guest

    Re: Doevents causes 100% CPU load?!?

    Hi Felix,

    > What's wrong / How can I achieve 0% cpu load while idling?


    Use a Timer instead of a loop. <g> Seriously, VB is event-driven by nature and it's a bit
    like forcing a square peg through a round hole to get it to behave procedurally.

    > I don't think
    > that the API call "sleep" will work for me as my thread is doing a lot of
    > stuff in the background and it must not be blocked.


    If you run a tight loop, you are going to peg the CPU usage. DoEvents does let other
    processes run, so adding a "Sleep 1" line to a loop that has a DoEvents in it isn't going
    to significantly change the behaviour of your code, and it will drop the CPU usage down to
    almost nothing.

    What do you mean by "doing a lot of stuff in the background and it must not be blocked."?
    You only have one thread of execution. If you're in a tight loop and don't want to be
    interrupted, then you will max the CPU. If you want to go easy on the CPU and not allow
    events in your app to process, then stay in the loop, call Sleep, and get rid of the
    DoEvents.

    If you want to respond to user input without calling DoEvents every iteration, you can use
    the
    GetInputState API to test for input, then call DoEvents if it evaluates to True.

    You can also just call DoEvents every so many iterations instead of every time.

    HTH,

    Pete Young



  7. #7
    Peter Young Guest

    Re: Doevents causes 100% CPU load?!?

    Hi Felix,

    > What's wrong / How can I achieve 0% cpu load while idling?


    Use a Timer instead of a loop. <g> Seriously, VB is event-driven by nature and it's a bit
    like forcing a square peg through a round hole to get it to behave procedurally.

    > I don't think
    > that the API call "sleep" will work for me as my thread is doing a lot of
    > stuff in the background and it must not be blocked.


    If you run a tight loop, you are going to peg the CPU usage. DoEvents does let other
    processes run, so adding a "Sleep 1" line to a loop that has a DoEvents in it isn't going
    to significantly change the behaviour of your code, and it will drop the CPU usage down to
    almost nothing.

    What do you mean by "doing a lot of stuff in the background and it must not be blocked."?
    You only have one thread of execution. If you're in a tight loop and don't want to be
    interrupted, then you will max the CPU. If you want to go easy on the CPU and not allow
    events in your app to process, then stay in the loop, call Sleep, and get rid of the
    DoEvents.

    If you want to respond to user input without calling DoEvents every iteration, you can use
    the
    GetInputState API to test for input, then call DoEvents if it evaluates to True.

    You can also just call DoEvents every so many iterations instead of every time.

    HTH,

    Pete Young



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center