A simple search for DoEvents
brings up lots of results that lead, basically, to:
DoEvents
is evil. Don't use it. Use threading instead.
The reasons generally cited are:
- Re-entrancy issues
- Poor performance
- Usability issues (e.g. drag/drop over a disabled window)
But some notable Win32 functions such as TrackPopupMenu
and DoDragDrop
perform their own message processing to keep the UI responsive, just like DoEvents
does.
And yet, none of these seem to come across these issues (performance, re-entrancy, etc.).
How do they do it? How do they avoid the problems cited with DoEvents
? (Or do they?)
Back in 16-bit Windows days, when every task shared a single thread, the only way to keep a program responsive within a tight loop was
DoEvents
. It is this non-modal usage that is discouraged in favor of threads. Here's a typical example:For modal things (like tracking a popup), it is likely to still be OK.
DoEvents() is dangerous. But I bet you do lots of dangerous things every day. Just yesterday I set off a few explosive devices (future readers: note the original post date relative to a certain American holiday). With care, we can sometimes account for the dangers. Of course, that means knowing and understanding what the dangers are:
Re-entry issues. There are actually two dangers here:
Performance Issues. DoEvents() can give the illusion of multi-threading, but it's not real mutlithreading. This has at least three real dangers:
Usability Issues. These are side-effects that result from not properly accounting for the other dangers. There's nothing new here, as long as you looked in other places appropriately.
If you can be sure you accounted for all these things, then go ahead. But really, if DoEvents() is the first place you look to solve UI responsiveness/updating issues, you're probably not accounting for all of those issues correctly. If it's not the first place you look, there are enough other options that I would question how you made it to considering DoEvents() at all.
The reality is that most of the time, at least in the .Net world, a BackgroundWorker component is nearly as easy, at least once you've done it once or twice, and it will do the job in a safe way. More recently, the async/await pattern or the use of a
Task
can be much more effective and safe.I may be wrong, but it seems to me that
DoDragDrop
andTrackPopupMenu
are rather special cases, in that they take over the UI, so don't have the reentrancy problem (which I think is the main reason people describeDoEvents
as "Evil").Personally I don't think it's helpful to dismiss a feature as "Evil" - rather explain the pitfalls so that people can decide for themselves. In the case of
DoEvents
there are rare cases where it's still reasonable to use it, for example while a modal progress dialog is displayed, where the user can't interact with the rest of the UI so there is no re-entrancy issue.Of course, if by "Evil" you mean "something you shouldn't use without fully understanding the pitfalls", then I agree that
DoEvents
is evil.