No announcement yet.

Sleep/DoEvents Question

  • Filter
  • Time
  • Show
Clear All
new posts

  • Sleep/DoEvents Question

    In Help, the Dialog DoEvents and Sleep topics, is this text:

    If m& is zero, the remainder of the current time-slice is relinquished. If there are no other threads of equal priority, execution continues immediately.
    But both also have this:

    allowing other processes (or threads) to continue.
    These seem slightly at odds. If there are other processes, then doesn't "...continues immediately" let "...other processes to continue", rather than continuing immediately?

    So does Sleep 0 immediately start the thread when there are no other threads of equal priority, or does it instead yield time slice to any existing processes.

    But then there's this:

    During the SLEEP period, all time-slices for the current thread are given to other threads and processes.
    If I tried to guess what is meant, this would be my guess:
    Sleep 0 - yields to threads only
    Sleep <not 0> - yields to threads and processes

    And finally, Dialog DoEvents help topic says this:

    Process pending window or dialog messages for MODELESS dialogs.
    It says nothing about using Dialog DoEvents in a MODAL dialog. However, I've used, and seen used, Dialog DoEvents in MODAL dialogs. But from reading Help, one would first guess that it is not to be used for MODAL dialogs. Zale once stated that if Help doesn't say you can do it, DON'T - but I've been breaking that rule.

    None of this has kept me from using the statements, but it would seem that my use and the documentation may not be in sync.

  • #2
    Asking the question raised more questions.

    Thinking more on the documentation, there are 5 statements of interest

    Sleep 0 - yields rest of current time slice, pauses only for that long
    Sleep n - pauses for n ms, yields all time slices during the pause time
    DoEvents sleep 0
    DoEvents sleep 1 (default if sleep left off)
    DoEvents sleep n

    The DoEvents sleep x statements are identical in effect to the stand alone Sleep statements - except that regardless of the value of x, all pending dialog messages are processed. (but for which dialog, since DoEvents doesn't ask for one)

    Why does one thread need to pause for another to be allowed to continue?

    How is "processing messages" different than yielding time-slices, especially if another thread takes an action that generates a message?

    My GUT (grand unified theory of these concepts) is not complete.
    Last edited by Gary Beene; 16 Sep 2009, 12:02 PM.


    • #3
      Continuing with thoughts ...

      Processing messages is a Main thread activity, can span multiple dialogs?

      Dialog DoEvents and Sleep affect only the thread in which they are executed.

      Is DoEvents a Main thread action - or, can a thread run Dialog DoEvents, just like a Main thread? I assume so. But when you run DoEvents, which thread pauses if you execute DoEvents in a 2nd thread?

      If a thread creates a dialog, does running Dialog DoEvents in that thread process messages for the 2nd dialog or for all dialogs?

      I suppose if I had been using threads for years, this would be old hat. But I haven't, and it is not.


      • #4
        I'm on a roll, talking to myself here!

        So, this thought just in,

        PowerBASIC Inc meant for DIALOG DOEVENTS to be used ONLY in a message pump for modeless dialogs (not inside any dialog, modal or modeless).

        The SLEEP statement is for use inside an application.

        Since a MODAL dialog does it's own message processing, using the DIALOG DOEVENTS inside a MODAL dialog only has an effect because of the its SLEEP part.

        So inside a MODAL dialog, both DOEVENTS and SLEEP have the same effect.

        Bottom line, you can use both inside any dialog, but might as well use SLEEP since DOEVENTS is just a SLEEP wrapper when used inside a dialog.

        Perhaps my VB6 experience, of having a VB6 DoEvents statement that was used inside an application, predisposed me to think of the DoEvents as an inside-the-app statement, rather than perhaps the intent of the PowerBASIC DoEvents.
        Last edited by Gary Beene; 16 Sep 2009, 01:16 PM.


        • #5
          If you have questions about SLEEP or DIALOG DOEVENTS which are not covered in the documentation to your satisfactio, you simply have to go to the publisher for more detail.

          Many of us can "make a guess" about what's going on 'under the hood' , and while it will likely be a "good guess" .....
          A. It's still only a guess
          B. It may not apply to all versions of the compiler. (eg DIALOG DOEVENTS has changed its behavior across versions)

          FWIW however, Windows allocates CPU use by THREAD, not PROCESS. (two of 'those words' we discussed a few weeks ago)

          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]


          • #6
            And as far as using DIALOG DOEVENTS somewhere other than your "message loop"...

            This is just style, but for my nineteen cents the 'need' to do this shows a lack of planning and/or coding technique on the part of the programmer.

            You should basically never need to "force" an update to a screen, unless you have done something to prevent "the natural order of things" from occurring. Windows DOES provide the ability to override this "natural" order of things (e.g, see "DeferWindowPos()" and related WinAPI functions), but for the most part these tools are only needed for optimization of graphics-intensive stuff.

            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]


            • #7

              I think you missed my point.

              In another world, DoEvents was apparently the equivalent of the PowerBASIC SLEEP and was used inside an application, not inside a message pump.

              So at times, when I've wanted to give CPU time to somewhere other than a loop I was in, I tried the Dialog DoEvents and it actually worked. The point of my last post was that in PowerBASIC, the Dialog DoEvents was apparently designed as a message pump enabler, with Sleep capabilities thrown in as well.

              So when I've used Dialog DoEvents inside the app and outside the message pump, I got useful results because of it's sleep capabilities, not because I wanted it's message processing capabilities. As someone else noted, Dialog DoEvents has no effect on processing of modal dialog messages, which is what I typically use.

              When a question came up recently, I looked at Help in more detail and realized the content described using DoEvents and Sleep differently than I had assumed was intended.

              Your comment about screen updates caught me by surprise too. I wasn't thinking that the message processing features of Dialog DoEvents was primarily useful for screen updates. I assumed Dialog Redraw was the tool for that, however in your SDK world the Paint event code would be accessed when a Dialog DoEvents was used in a modeless dialog message pump - so I can see why you might have gone in that direction.

              I'm assuming, as my last post implied, that I'm safer keeping Dialog DoEvents out of the dialog and should use it solely for the message pump of a modeless dialog as its designers apparently intended. As you noted, guarantees of its feature set (especially in an undocumented way) aren't something you want to bank your app on.


              • #8
                So at times, when I've wanted to give CPU time to somewhere other than a loop I was in, I tried the Dialog DoEvents and it actually worked.
                Code not shown, but assuming you mean you used the PB SLEEP or DIALOG DOEVENTS statements, no, it did not "work". Those functions only have the documented ability to relinquish the rest of the thread's timeslice back to the operating system; once relinquished, Windows decides what thread to run, not you.

                However.... if you really really want to control usage within YOUR current timeslice for your current thread of execution, you need to read up on "Fibers." (Warning: not for the faint of heart!)

                that I'm safer keeping Dialog DoEvents out of the dialog and should use it solely for the message pump of a modeless dialog as its designers apparently intended.
                No, I don't think it's any more safe or dangerous. I just think it's a <expletive deleted> way to write code.

                Nor do I have any idea just what the designers intended.

                guarantees of its feature set (especially in an undocumented way) aren't something you want to bank your app on.
                Now THAT has a "safe/dangerous" context, for sure.

                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]


                • #9
                  I see where Gary is going (as a VB-refugee) and timing koinky-dink was looking at the same lines at the time I think I can add the same question along with a twist (See "apiSleep" in the Win32Api file for details)

                  my best "Guesstimate" is that sleep really does the following:
                  1.) Pause your code
                  2.) Allow other threads or apps to "Catch Up" if they are waiting
                  3.) if nothing waiting then your code continues if your amount of time has finished.

                  Am I wrong? right? misunderstood

                  my VB days would let me push a button to abort any loops I had running....but I get why a message of "Woops wait a sec...things changed so abort what you were working on" comes into play
                  Engineer's Motto: If it aint broke take it apart and fix it

                  "If at 1st you don't succeed... call it version 1.0"

                  "Half of Programming is coding"....."The other 90% is DEBUGGING"

                  "Document my code????" .... "WHYYY??? do you think they call it CODE? "


                  • #10
                    It goes something like this:

                    Each thread is allocated 1 timeslice at a time by the OS.

                    A thread which works for the whole time will be forcibly interupted by the OS at the end of that timeslice and control will be given to the next thread which the OS deems needs it most. Which thread get it depends on the thread priorities and how long it is since the thread last had a timeslice.

                    If a thread has nothing to do then it can give up its current timeslice using SLEEP to allow other threads to make use of it.

                    SLEEP 0 gives up the remainder of the current timeslice but indicates that the thread is still in need of CPU time so the OS will go around the rest of the threads just as if the timeslice was finished and return to the current thread as soon as it gets around to rescheduling it. This could be immediately if no other thread needs a timeslice when SLEEP 0 is executed.

                    SLEEP N will give up the current timeslice and indicates that no more time will be needed for at least N msecs. If no other thread needs time then the time is allocated to CPU idle time. There is no guarantee that control will return in N msecs as this is a minimum time. If lots of other threads are running then each will get their turn before the current thread is rescheduled so it could be a lot longer than N msecs.

                    SLEEP 1 gives up the minimum timeslice time. A timeslice is typically 15msec so sleep 1 will give wait for at least 15 msec before recheduling the thread but if the OS has a shorter timeslice then that minimum time is used instead.