Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. How does Application.DoEvents work?

How does Application.DoEvents work?

Scheduled Pinned Locked Moved .NET (Core and Framework)
questioncsharpdata-structures
16 Posts 11 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Johann Gerell

    Luc Pattyn wrote:

    you can have as many pumps as you like.

    Correct.

    Luc Pattyn wrote:

    a dialog, it has its own message pump

    In general not correct. However, modal dialogs usually have their own message pump.

    Time you enjoy wasting is not wasted time - Bertrand Russel

    L Offline
    L Offline
    Luc Pattyn
    wrote on last edited by
    #6

    that is what I meant, to me a dialog is a modal window and a modal dialog a tautology. :)

    Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

    Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

    1 Reply Last reply
    0
    • G Guy Harwood

      I thought this question was going to be about the access function (does the same kind of thing) *shudders at recollection of coding in access*

      ---Guy H ;-)---

      M Offline
      M Offline
      Mike Devenney
      wrote on last edited by
      #7

      Guy Harwood wrote:

      *shudders at recollection of coding in access*

      Ahh the heady days of my youth spent coding VBA... I can barely remember what it was like to end a line of code without a semicolon and have a hard time doing it when I wander into VBA to trick out a macro in Excel for a co-worker these days. Makes me feel old to think of how long ago that was (mid 90's). :omg:

      Mike Devenney

      1 Reply Last reply
      0
      • L Luc Pattyn

        There is no such thing as "the message pump", i.e. you can have as many pumps as you like. Example: when you show a dialog, it has its own message pump, which processes messages related to the dialog and ignores the others. DoEvents() looks like yet another message pump, which processes everything until there are no more messages, then returns. And it is pretty dangerous to call DoEvents() from within an event handler, as it may cause that very handler to be called again, i.e. it may re-enter which you probably did not intend nor anticipate. :)

        Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

        Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

        S Offline
        S Offline
        Spectre_001
        wrote on last edited by
        #8

        Windows under the hood is still basicaly a non-preemptive multitasking OS, meaning that on a given processor core, individual threads are allocated execution time slices by the system one at a time. During your thread's slice of time, your application has the core and can execute as long as it sees fit, returning to the system when you are done. In such an OS for an application to "play nice" with others, if you running a long execution, you would intersperce your code with DoEvents (especially if you have a long running loop, you put a DoEvents in the loop) to allow the OS to have a timeslice to perform it's housekeeping routines, send pending messages, etc.. In other words, DoEvents allows your code to return execution to the OS for a timeslice then execution returns to you where you left off. This is especially handy if you are coding a Windows Forms app that updates it's screen elements as your code is running (example a progress bar). If you don't allow the OS a timeslice to send messages to your program to re-draw, your window will seem to freeze untill your long running process is finished and execution is returned to the OS (your app's screen won't redraw).

        Kevin Rucker, Application Programmer QSS Group, Inc. United States Coast Guard OSC Kevin.D.Rucker@uscg.mil "Programming is an art form that fights back." -- Chad Hower

        L 1 Reply Last reply
        0
        • S Spectre_001

          Windows under the hood is still basicaly a non-preemptive multitasking OS, meaning that on a given processor core, individual threads are allocated execution time slices by the system one at a time. During your thread's slice of time, your application has the core and can execute as long as it sees fit, returning to the system when you are done. In such an OS for an application to "play nice" with others, if you running a long execution, you would intersperce your code with DoEvents (especially if you have a long running loop, you put a DoEvents in the loop) to allow the OS to have a timeslice to perform it's housekeeping routines, send pending messages, etc.. In other words, DoEvents allows your code to return execution to the OS for a timeslice then execution returns to you where you left off. This is especially handy if you are coding a Windows Forms app that updates it's screen elements as your code is running (example a progress bar). If you don't allow the OS a timeslice to send messages to your program to re-draw, your window will seem to freeze untill your long running process is finished and execution is returned to the OS (your app's screen won't redraw).

          Kevin Rucker, Application Programmer QSS Group, Inc. United States Coast Guard OSC Kevin.D.Rucker@uscg.mil "Programming is an art form that fights back." -- Chad Hower

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #9

          Spectre_001 wrote:

          Windows under the hood is still basicaly a non-preemptive multitasking OS

          I don't agree. The Windows kernel is event driven, is priority based, is pre-emptive, has fairness implemented, and contains some protection against CPU monopolizing processes. There is no need to call DoEvents(), or anything else, at all to get things to work properly. Here is a simple test: create a process that contains a long computation and have it optionally generate output while computing; now run a number of instances and watch how each of them is proceeding. Windows is not a real-time OS, which means it is not guaranteeing much on latency; however it does not need the user's cooperation to provide a good interactive user experience. There are ways to make an app behave badly, one of them would be to execute long or blocking stuff on a WinApp's main thread; and there are ways to make an app fail, one of them is calling Application.DoEvents() causing code to get re-entered while it wasn't designed for re-entrance to start with. BTW: none of the misbehavior mentioned (block GUI thread, call DoEvents) would negatively affect other processes. :)

          Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

          Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

          1 Reply Last reply
          0
          • M MicroVirus

            Hello coders, I've been wondering this for some time, but haven't been able to find an answer to: How does DoEvents actually work (technically seen)? The way I look at it, you have this picture describing your single-threaded application: [ Your code ] [ Translation to .NET events ] [ Message Pump ] With basically messages coming in from Windows at the Message Pump level, then advancing up until it reaches your code in terms of Events. Your code runs etcetera, and whenever execution 'pauses' (e.g. disappears when debugging), the message pump gets execution again and handles messages. Somewhere parallel is the garbage collector, asynchronously cleaning up your mess in collect 'n reap batches. Am I at least right about this picture (if not, then my question might not make sense)? The actual question then is: how does DoEvents, called from your code, manage to fall back into the Message Pump? I'd think you need to re-enter the calling function, so basically advance through the stack back to the caller, without losing all the context allowing you to move up to your original point of execution. That means that a simple call to the message pump 'function' would not be the way to, because then it would end up a top of the stack. One solution to this I was thinking of was to use something like SendMessage(WM_USER_IDLE, ...) to get back into the message pump, but is that even possible/allowed? Does anyone know the answer, because I am REALLY curious :) Thanks for reading my rant, and I'll hope you have some answers, Richard

            P Offline
            P Offline
            Patrick Fox
            wrote on last edited by
            #10

            Reflector is your friend: public static void DoEvents() { ThreadContext.FromCurrent().RunMessageLoop(2, null); } If you keep poking deeper, you see that it's just running a message loop to handle any messages that might have been sent.

            1 Reply Last reply
            0
            • M MicroVirus

              Hello coders, I've been wondering this for some time, but haven't been able to find an answer to: How does DoEvents actually work (technically seen)? The way I look at it, you have this picture describing your single-threaded application: [ Your code ] [ Translation to .NET events ] [ Message Pump ] With basically messages coming in from Windows at the Message Pump level, then advancing up until it reaches your code in terms of Events. Your code runs etcetera, and whenever execution 'pauses' (e.g. disappears when debugging), the message pump gets execution again and handles messages. Somewhere parallel is the garbage collector, asynchronously cleaning up your mess in collect 'n reap batches. Am I at least right about this picture (if not, then my question might not make sense)? The actual question then is: how does DoEvents, called from your code, manage to fall back into the Message Pump? I'd think you need to re-enter the calling function, so basically advance through the stack back to the caller, without losing all the context allowing you to move up to your original point of execution. That means that a simple call to the message pump 'function' would not be the way to, because then it would end up a top of the stack. One solution to this I was thinking of was to use something like SendMessage(WM_USER_IDLE, ...) to get back into the message pump, but is that even possible/allowed? Does anyone know the answer, because I am REALLY curious :) Thanks for reading my rant, and I'll hope you have some answers, Richard

              F Offline
              F Offline
              Fabio Franco
              wrote on last edited by
              #11

              I beleive DoEvents call moves the pointer on the call stack to where the Windows Messages are, saving the current point and then returning to it after the windows messages are processed. Of course not this over simplified but I beleive the logic works this way...

              T 1 Reply Last reply
              0
              • F Fabio Franco

                I beleive DoEvents call moves the pointer on the call stack to where the Windows Messages are, saving the current point and then returning to it after the windows messages are processed. Of course not this over simplified but I beleive the logic works this way...

                T Offline
                T Offline
                the Kris
                wrote on last edited by
                #12

                That is not correct. The Windows Message queue is not "on" the stack. No weird call stack operations are performed. For .Net Application.Run() and Application.DoEvents() are somewhat similar in that they both call a message pump. A message pump could be very simply be:

                MessagePump()
                {
                while ( true )
                {
                Message msg = GetMessage(); // Get the next message from the queue
                DispatchMessage( msg ); // This will do the work
                if ( msg.Msg == WM_QUIT ) break;
                }
                }

                The code behind DispatchMessage will eventually call your events, e.g. when a button is clicked. If you then do a form.ShowDialog() it will re-enter the message pump function (recursively, the previous call just stays on the call stack). This is why showing a message box in a timer event handler will result in stacking up message boxes until resources are exhausted or a stack overflow occurs. The call stack will look something like this (looking at it top-down) :

                Application.Run
                MessagePump
                DispatchMessage
                ... framework stuff ...
                Timer1.TimerEvent
                SomeForm.ShowDialog
                Application.DoEvents
                MessagePump
                DispatchMessage
                ... framework stuff ...
                Timer1.TimerEvent
                SomeForm.ShowDialog <-- if you indeed do this call then this will repeat until...

                modified on Wednesday, September 8, 2010 2:36 PM

                F 1 Reply Last reply
                0
                • T the Kris

                  That is not correct. The Windows Message queue is not "on" the stack. No weird call stack operations are performed. For .Net Application.Run() and Application.DoEvents() are somewhat similar in that they both call a message pump. A message pump could be very simply be:

                  MessagePump()
                  {
                  while ( true )
                  {
                  Message msg = GetMessage(); // Get the next message from the queue
                  DispatchMessage( msg ); // This will do the work
                  if ( msg.Msg == WM_QUIT ) break;
                  }
                  }

                  The code behind DispatchMessage will eventually call your events, e.g. when a button is clicked. If you then do a form.ShowDialog() it will re-enter the message pump function (recursively, the previous call just stays on the call stack). This is why showing a message box in a timer event handler will result in stacking up message boxes until resources are exhausted or a stack overflow occurs. The call stack will look something like this (looking at it top-down) :

                  Application.Run
                  MessagePump
                  DispatchMessage
                  ... framework stuff ...
                  Timer1.TimerEvent
                  SomeForm.ShowDialog
                  Application.DoEvents
                  MessagePump
                  DispatchMessage
                  ... framework stuff ...
                  Timer1.TimerEvent
                  SomeForm.ShowDialog <-- if you indeed do this call then this will repeat until...

                  modified on Wednesday, September 8, 2010 2:36 PM

                  F Offline
                  F Offline
                  Fabio Franco
                  wrote on last edited by
                  #13

                  That's exactly what I meant, for example, if our heavy processing code is inside DispatchMessage, it might simply do "Goto address 1" as exemplified below and push the current address on the stack so it can be popped after the goto call finishes:

                  MessagePump()
                  {
                  while ( true )
                  {
                  Adr 1 Message msg = GetMessage(); // Get the next message from the queue
                  Adr 2 DispatchMessage( msg ); // This will do the work
                  Adr 3 if ( msg.Msg == WM_QUIT ) break;
                  }
                  }

                  Again, that's how I think it works.

                  1 Reply Last reply
                  0
                  • M MicroVirus

                    Hello coders, I've been wondering this for some time, but haven't been able to find an answer to: How does DoEvents actually work (technically seen)? The way I look at it, you have this picture describing your single-threaded application: [ Your code ] [ Translation to .NET events ] [ Message Pump ] With basically messages coming in from Windows at the Message Pump level, then advancing up until it reaches your code in terms of Events. Your code runs etcetera, and whenever execution 'pauses' (e.g. disappears when debugging), the message pump gets execution again and handles messages. Somewhere parallel is the garbage collector, asynchronously cleaning up your mess in collect 'n reap batches. Am I at least right about this picture (if not, then my question might not make sense)? The actual question then is: how does DoEvents, called from your code, manage to fall back into the Message Pump? I'd think you need to re-enter the calling function, so basically advance through the stack back to the caller, without losing all the context allowing you to move up to your original point of execution. That means that a simple call to the message pump 'function' would not be the way to, because then it would end up a top of the stack. One solution to this I was thinking of was to use something like SendMessage(WM_USER_IDLE, ...) to get back into the message pump, but is that even possible/allowed? Does anyone know the answer, because I am REALLY curious :) Thanks for reading my rant, and I'll hope you have some answers, Richard

                    E Offline
                    E Offline
                    englebart
                    wrote on last edited by
                    #14

                    This is low level Windows API view, not sure how dotNET sits on top. 1. Each Thread can have its own message pump if needed. If you have windows created on multiple threads, they can run separately. (97% sure) 2. A modal dialog must provide a new message pump, because it is called from the current stack of the "calling" message pump. The "calling" message pump is frozen until the modal dialog's pump exits. This is how you can get a return value from the Modal dialog during the event dispatching of the calling pump. This is also the case with Menus. The event handler for the menu is called from a different pump. 3. Prior to Windows XP(?), the only way to share the cpu with other Windows apps was when calling GetMessage() or PeekMessage(). It really was "play nice or don't play at all." You had to make sure that you "chunked" background work in such a way that you invoked PeekMessage() occasionally. I am pretty sure that even Windows 95/98?/ME? were 32bit wrappers around the same old Windows 1.0 core. Pre-emption was enforced on DOS virtual machines, but all Windows apps ran in the same VM. This was great because you could actually locate and read memory structures out of other running programs on the system! WinNT families were pre-emptive and full protected memory spaces out of the starting block. There is probably a windows genealogy somewhere that says when certain features were introduced when.

                    1 Reply Last reply
                    0
                    • M MicroVirus

                      Hello coders, I've been wondering this for some time, but haven't been able to find an answer to: How does DoEvents actually work (technically seen)? The way I look at it, you have this picture describing your single-threaded application: [ Your code ] [ Translation to .NET events ] [ Message Pump ] With basically messages coming in from Windows at the Message Pump level, then advancing up until it reaches your code in terms of Events. Your code runs etcetera, and whenever execution 'pauses' (e.g. disappears when debugging), the message pump gets execution again and handles messages. Somewhere parallel is the garbage collector, asynchronously cleaning up your mess in collect 'n reap batches. Am I at least right about this picture (if not, then my question might not make sense)? The actual question then is: how does DoEvents, called from your code, manage to fall back into the Message Pump? I'd think you need to re-enter the calling function, so basically advance through the stack back to the caller, without losing all the context allowing you to move up to your original point of execution. That means that a simple call to the message pump 'function' would not be the way to, because then it would end up a top of the stack. One solution to this I was thinking of was to use something like SendMessage(WM_USER_IDLE, ...) to get back into the message pump, but is that even possible/allowed? Does anyone know the answer, because I am REALLY curious :) Thanks for reading my rant, and I'll hope you have some answers, Richard

                      S Offline
                      S Offline
                      Scott Barbour
                      wrote on last edited by
                      #15

                      I'm surprised that no one has pointed to MSDN for this: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx[^] I know MSDN isn't always helpful, but it tells you what it does as well as when to use it and when not to use it. Realistically, most circumstances where it is not safe to call DoEvents indicates that you are doing something wrong (such as raising the event in its own handler). Note: the emphasis is on "most" since there are exceptions to almost every rule.

                      I don't claim to be a know it all, for I know that I am not...

                      I usually have an answer though.

                      M 1 Reply Last reply
                      0
                      • S Scott Barbour

                        I'm surprised that no one has pointed to MSDN for this: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx[^] I know MSDN isn't always helpful, but it tells you what it does as well as when to use it and when not to use it. Realistically, most circumstances where it is not safe to call DoEvents indicates that you are doing something wrong (such as raising the event in its own handler). Note: the emphasis is on "most" since there are exceptions to almost every rule.

                        I don't claim to be a know it all, for I know that I am not...

                        I usually have an answer though.

                        M Offline
                        M Offline
                        MicroVirus
                        wrote on last edited by
                        #16

                        MSDN unforunately doesn't say HOW it does it, which was what I wanted to know. I pretty much always check MSDN; I find it very helpful. I already have a lot of experience using DoEvents in a correct way in VB6. With .NET I much prefer a worker thread though, for many reasons. Thanks for all the responses :)

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups