Events? Who needs events!



  • We write software used by thousands of people in the health industry within Australia. Our software has over 80% market share in what we do. The following literally made my jaw drop:

    Do Until gblnNextImage = True Or gblnPrevImage = True Or gblnUrgentImage = True Or gblnCommitBatch = True Or gblnExit = True
         Do_some_very_light_processing_with_no_sleep
         Do Events
    Loop

    Elsewhere, we have menu commands that perform actions such as this:

    Private Sub mnuExit_Click()
        'Unload frmManualimgProcess
        gblnExit = True
    End Sub

     Can anyone else figure out why the process was using 100% CPU? I admit to saying sod it and just sticking a Sleep 200 call in there.



  • I've done that.  Those Sleep(200)s do wonders for application performance.  I've found that the Sleep(150)s do better, but not as well as the Sleep(182.3)s.



  • Ofcourse your fix was:

    'Do more events to save CPU resources
    For I = 0 to 100000
        Do Events
    Next

    Right? 



  • Sleeping for some fixed amount of time is usually a (somewhat medium) WTF in itself.

     

    A better approach is to use a bounded and self-adjusting sleep loop, something like:

     

    MinSleep = 5; MaxSleep = 2000; 

    SleepTime = ( MinSleep + MaxSleep ) / 2 ; 

    while not done

      DidStuff = TryDoingStuff();

      if DidStuff then SleepTime = max( MinSleep, SleepTime / 2 )  else SleepTime = min( MaxSleep, SleepTime * 2)

      Sleep( SleepTime );

    end while

     


     


     

     



  • @DaEagle said:

    We write software used by thousands of people in the health industry within Australia. Our software has over 80% market share in what we do. The following literally made my jaw drop:

    Do Until gblnNextImage = True Or gblnPrevImage = True Or gblnUrgentImage = True Or gblnCommitBatch = True Or gblnExit = True
         Do_some_very_light_processing_with_no_sleep
         Do Events
    Loop

     Can anyone else figure out why the process was using 100% CPU? I admit to saying sod it and just sticking a Sleep 200 call in there.

    I don't have much VB6 experience but as far as I know the "loop with Do Events in it" is fairly standard practice.  I'm pretty sure VB6 doesn't even have a sleep command, you have to declare the WinAPI sleep function to use it.  It sounds like the real issue is that the Do_some_very_light_processing_with_no_sleep part shouldn't be running in the background all the time (it might make more sense to put it in a Timer_Tick event).
     



  • @burnmp3s said:

    I don't have much VB6 experience but as far as I know the "loop with Do Events in it" is fairly standard practice.  I'm pretty sure VB6 doesn't even have a sleep command, you have to declare the WinAPI sleep function to use it.  It sounds like the real issue is that the Do_some_very_light_processing_with_no_sleep part shouldn't be running in the background all the time (it might make more sense to put it in a Timer_Tick event).

    QBasic did have a sleep command if I remember right (sleeps for X seconds unless you press a key?)

    Loop with do events is standard practice for people that don't get event based programming. Just because many people do it doesn't mean it's the right way and does not deserve a WTF. To bad VB6 does not supply a "wait for event X" option. As that would solve some issues. The only good reason to use Do Events is to show the user that the program is still alive, and give the user a chance to press cancel on whatever number crushing you are doing.
     



  • @burnmp3s said:

    @DaEagle said:

    We write software used by thousands of people in the health industry within Australia. Our software has over 80% market share in what we do. The following literally made my jaw drop:

    Do Until gblnNextImage = True Or gblnPrevImage = True Or gblnUrgentImage = True Or gblnCommitBatch = True Or gblnExit = True
         Do_some_very_light_processing_with_no_sleep
         Do Events
    Loop

     Can anyone else figure out why the process was using 100% CPU? I admit to saying sod it and just sticking a Sleep 200 call in there.

    I don't have much VB6 experience but as far as I know the "loop with Do Events in it" is fairly standard practice.  I'm pretty sure VB6 doesn't even have a sleep command, you have to declare the WinAPI sleep function to use it.  It sounds like the real issue is that the Do_some_very_light_processing_with_no_sleep part shouldn't be running in the background all the time (it might make more sense to put it in a Timer_Tick event).
     

    I have lots of VB6 experience and no "loop with do events" is not standard practice.  It is only standard with inexperienced developers.  Granted VB6 had trouble creating a true "wait until something happens" process, but the standard way of doing this was to have the code in a timer function so the app "wakes up" and checks if it needs to do something.

    Of course this only really applies to windows service style development and even then, vb6 needed a form that was never shown to host the timer, unless you were a brave one and created a timer in code.  But to really get sevices you needed the ServiceOCX unsupported from Microsoft, and that had to be hosted on a form anyway.

    Doing this in a standard app would get you a major chewing out if you were on my team. 



  • @Daid said:

    Loop with do events is standard practice for people that don't get event based programming. Just because many people do it doesn't mean it's the right way and does not deserve a WTF. To bad VB6 does not supply a "wait for event X" option. As that would solve some issues. The only good reason to use Do Events is to show the user that the program is still alive, and give the user a chance to press cancel on whatever number crushing you are doing.

    When I say Do Events is standard practice I mean something like this:

    'Open 1000 files

    Do

       OpenNextFile()

       If FilesLeftToOpen() < 1 Then Exit Do

       Do Events

    Loop While Not canceled 'Check if user clicked the cancel button



  • Hmmm, getting around using events by setting variables.... within an event.

    I should say that I'm shocked to see this in actual commercial software, but I'm not. It is absolute standard fair in in-house apps, though. Considering that this is VB6 (or earlier) code, it's most likely been written by someone who gained their "programming" skills on a C64 or some other non-event-based BASIC platform. Running through an infinite loop waiting for a key to be pressed or something was just how things where done back then.
     

    The worst that I've seen along these lines involved an array of dozens (hundreds? can't remember for sure) of timers, each firing off their own event checking for one particular thing.
     



  • @DaEagle said:

    We write software used by thousands of people in the health industry within Australia. Our software has over 80% market share in what we do. The following literally made my jaw drop:

    Do Until gblnNextImage = True Or gblnPrevImage = True Or gblnUrgentImage = True Or gblnCommitBatch = True Or gblnExit = True
         Do_some_very_light_processing_with_no_sleep
         Do Events
    Loop

    Elsewhere, we have menu commands that perform actions such as this:

    Private Sub mnuExit_Click()
        'Unload frmManualimgProcess
        gblnExit = True
    End Sub

     Can anyone else figure out why the process was using 100% CPU? I admit to saying sod it and just sticking a Sleep 200 call in there.

    Do Events will not stop the CPU from using 100% of available cycles.  Do Events will simply make you UI respond to inputs.  The problem is, you are in a tight loop.  Your Do_some_very_light_processing_with_no_sleep gets called every time you run through the loop.  As long as none of the booleans are true, you will take 100% CPU, not matter how light the processing is.

    Don't do Sleep 200.  That is a really, really bad idea.  As others have mentioned, the problem is that you are trying to do your own Event loop processing.  You want to use proper UI events and/or timers rather than setting a bunch of global booleans.  Oh, and globals...not such a good thing.

    Nitpick: why is it that VB coders always compare booleans to True or False?  Why say something like If IsError = True Then instead of just If IsError Then?  Is there some secret VB code style document out there that says always compare a boolean against True or False?!
     



  • @Grimoire said:

    Nitpick: why is it that VB coders always compare booleans to True or False?  Why say something like If IsError = True Then instead of just If IsError Then?  Is there some secret VB code style document out there that says always compare a boolean against True or False?!

    IntelliSense.  You never have to type out True or False because it shows up in the IntelliSense, so it only takes 2 more keystrokes to add the "= True".

    Also, unlike some other languages, VB doesn't have the whole "= vs. ==" source of bugs, so doing an equality test in an if statement never results in an accidental assignment.



  • @burnmp3s said:

    @Grimoire said:

    Nitpick: why is it that VB coders always compare booleans to True or False?  Why say something like If IsError = True Then instead of just If IsError Then?  Is there some secret VB code style document out there that says always compare a boolean against True or False?!

    IntelliSense.  You never have to type out True or False because it shows up in the IntelliSense, so it only takes 2 more keystrokes to add the "= True".

    Also, unlike some other languages, VB doesn't have the whole "= vs. ==" source of bugs, so doing an equality test in an if statement never results in an accidental assignment.

    But it takes zero more keystrokes to not hit the equals at all.  I agree with Grimoire that this style is just silly.  On the other hand, considering that I accumulated a few VB6 years in the 90's, I can refute his statement that VB coders "always" do it.



  • @wgh said:

    @burnmp3s said:
    @Grimoire said:

    Nitpick: why is it that VB coders always compare booleans to True or False?  Why say something like If IsError = True Then instead of just If IsError Then?  Is there some secret VB code style document out there that says always compare a boolean against True or False?!

    IntelliSense.  You never have to type out True or False because it shows up in the IntelliSense, so it only takes 2 more keystrokes to add the "= True".

    Also, unlike some other languages, VB doesn't have the whole "= vs. ==" source of bugs, so doing an equality test in an if statement never results in an accidental assignment.

    But it takes zero more keystrokes to not hit the equals at all.

     That is exactly what I thought when I read the 2 stroke comment.
     



  • @sycro said:

    @wgh said:
    @burnmp3s said:
    @Grimoire said:

    Nitpick: why is it that VB coders always compare booleans to True or False?  Why say something like If IsError = True Then instead of just If IsError Then?  Is there some secret VB code style document out there that says always compare a boolean against True or False?!

    IntelliSense.  You never have to type out True or False because it shows up in the IntelliSense, so it only takes 2 more keystrokes to add the "= True".

    Also, unlike some other languages, VB doesn't have the whole "= vs. ==" source of bugs, so doing an equality test in an if statement never results in an accidental assignment.

    But it takes zero more keystrokes to not hit the equals at all.

     That is exactly what I thought when I read the 2 stroke comment.

    My point was that it's easy to do and it doesn't cause bugs, so some people do it and some people don't.

    The reason why nobody does it in C and C++ is because it's slightly harder to do and it can cause multiple crazy bugs.  For example, in C some of the library functions return a boolean value of 2 or 3 (which is a WTF by itself).  Since TRUE = 1 and FALSE = 0 there are times when neither (value == FALSE) or (value == TRUE) evaluates to true.



  • @burnmp3s said:

    My point was that it's easy to do and it doesn't cause bugs, so some people do it and some people don't.

    The reason why nobody does it in C and C++ is because it's slightly harder to do and it can cause multiple crazy bugs.  For example, in C some of the library functions return a boolean value of 2 or 3 (which is a WTF by itself).  Since TRUE = 1 and FALSE = 0 there are times when neither (value == FALSE) or (value == TRUE) evaluates to true.

    And it is redundant.  An If statement needs a boolean.  You've got a boolean.  You're done.

     

    If you gave it a nice booleanish name, then it even reads better.

     



  • @Grimoire said:

    Do Events will not stop the CPU from using 100% of available cycles.  Do Events will simply make you UI respond to inputs.  The problem is, you are in a tight loop.  Your Do_some_very_light_processing_with_no_sleep gets called every time you run through the loop.  As long as none of the booleans are true, you will take 100% CPU, not matter how light the processing is.

    Don't do Sleep 200.  That is a really, really bad idea.  As others have mentioned, the problem is that you are trying to do your own Event loop processing.  You want to use proper UI events and/or timers rather than setting a bunch of global booleans.  Oh, and globals...not such a good thing.

    Maybe next time I'd better use the sarcasm tags. It's not worth fixing the application properly at this stage, hence the quick sleep fix. The applicaton is sitting there waiting to get converted into c# where it will bask in the glory of a true OO environment.


Log in to reply