DoEvents - History and appropriate usage

From REALbasicWiki

Jump to: navigation, search

DoEvents runs one iteration of the main event loop. This gives the UI a chance to update itself and post events. The RB framework's event-processing code expects to run only from the main thread. Running the event loop from a different thread will cause the usual problems you see when re-entering non-reentrant code. The initial implementation of DoEvents left this problem in the user's hands: it was up to you to know which thread you were running on.

After dozens of confusing bug reports, we decided that it made more sense to change DoEvents than to talk people out of abusing it. We added a check: if you call DoEvents from a secondary thread, it will yield rather than invoking the event loop. This doesn't guarantee that the GUI thread will run, but it's close enough that nobody notices the difference.

The remaining problem is easier to spot. You must make sure that there is no way any of the events raised by DoEvents can ever turn around and re-invoke the original code. For example, it might be a bad idea to call DoEvents from a timer action, because the call to DoEvents might re-invoke the timer, which would then trigger another call to DoEvents, ad infinitum. Hello, stack overflow exception.

The only appropriate use of DoEvents in a GUI app is to update the UI for a modal process, which generally means a modal dialog box. This is how Window.ShowModal works: it loops until the window is no longer visible, calling DoEvents on each iteration. This is safe as long as the rest of the UI is locked out, because it is impossible to begin another, simultaneous modal process.

If you are using DoEvents in a context that is analogous to Window.ShowModal, you are OK. If you are using it in some other way, you should rethink your design, but you are probably still OK.

We discourage use of DoEvents because it is a handy crutch for people who have not yet figured out event-driven, asynchronous programming. If you are thinking about your UI interaction in a stepwise, procedural fashion, it's easy to reach for DoEvents as a way to keep the controls working while you struggle along. This is a dead end. The point of the event-driven model is that your code does not sit in the driver's seat. You respond to user input one event at a time, updating your application's state in response to each interaction, and then you return. The user acts and your app reacts.

In summary: DoEvents is safe, as long as the events it triggers don't re-invoke it, and is appropriate when driving a modal UI process: but modal UI should be kept to a minimum, and any other use of DoEvents is a sign of design flaws.

Personal tools
related