Using Application.DoEvents() in real-time applications is dangerous!
Posted on | November 6, 2012 | No Comments
It has been numerously written that Application.DoEvents() method is not desirable, especially for high-performance applications. There are many reasons for this starting from message processing procedure and ending with non-evident problems with application response to user activity and code execution.
In most cases programmers use this method without thinking of consequences or its working principle. MSDN documentation says that this method processes messages in queue and when there are no more messages it stops working and passes control to the next code.
In simplified form this method looks as follows:
NativeUnsafeMethods.MSG msg;
while (PeekMessage(out msg))
{
TranslateMessage(ref msg);
DispatchMessage(ref msg);
}
However, we may wonder what happens when application is intensively rendering controls, synchronizing threads and performing other operations in GUI thread? In such situation message queue always contains messages that don’t let method finish its work. As the result, the end user won’t notice the difference in application behavior as Application.DoEvents() will process executing messages, including WM_PAINT messages, i.e. controls will be redrawn and the program will not slow down. However, code execution will stop on Application.DoEvents() method. If there are important operations after this method, they will not be executed until message queue is freed. We have often seen the situation when application was updating stock market prices and in times of high volatility prices were updated with noticeable delays!!!
A simple example of the problem is shown below. Demo application intensively synchronizes threads and paints data. Main GUI thread continuously processes messages (including synchronization messages and WM_PAINT messages). Clicking Start button calls Application.DoEvents() once, and in normal situation it should immediately return control to subsequent code. However, in this example the things are different! This method is followed by MessageBox.Show(…) that doesn’t display anything.
If demo application is fully covered with any other window or collapsed in the taskbar, Windows stops sending WM_PAINT messages and as the result of it message queue becomes empty, Application.DoEvents() method stops and MessageBox.Show(…) is executed.
Download DoEventsExample.zip
Therefore, before using Application.DoEvents() programmers should look at application architecture and ask themselves whether this method is really necessary. If application code really requires Application.DoEvents(), we have added Dapfor.Net.Editors.MessageQueueHelper class starting from version 2.8.4. This class has similar behavior but it also supports maximum execution time limit. If there are no more messages in queue, MessageQueueHelper also stops and passes control to the subsequent code.
Comments
Leave a Reply