Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

.NET

Application Responsiveness


How GUI Events Are Processed

To understand these points, it helps to understand how Windows GUI frameworks work. While there are subtle differences in the details, User32, Windows Forms, and WPF use the same general architecture (see Figure 1). Each window has a message queue and a single UI thread whose job it is to process messages from that queue. UI events, including user-initiated (clicks, window close requests, scrollbar dragging, and so on), system-initiated (paint requests), and application-initiated events are communicated via queuing a message, and are processed on this UI thread.

Figure 1: Windows GUI event architecture.

Code that manipulates UI elements must execute on the UI thread. This eliminates the overhead and pervasiveness that explicit synchronization in the programming model would impose (such as acquiring locks before updating elements) at the sacrifice of possible concurrency (see blogs.msdn.com/nickkramer). This means that:

  • Only the UI thread can run the message loop, which processes incoming events.
  • Code that must update a UI element must execute on the UI thread.

Because of the first point, anything the UI thread does—in addition to just dequeueing messages—impacts its ability to keep up with incoming messages. The most intuitive thing to do is simply write code that responds to an event in the UI element's event handlers. But because this work executes on the sole UI thread, it is often prudent to offload processing to a separate thread and, due to the second point, transition back to the UI thread to update visuals at specific intervals.

In WPF, similar to Windows Forms, modifications to System.Windows.Threading.DispatcherObject-derived objects must occur on the UI thread to execute. All visual types in WPF derive indirectly from this class. Each such object has a Dispatcher property of type Dispatcher, which an application can use to call Invoke or BeginInvoke to execute code synchronously or asynchronously, respectively, on the UI thread. These methods take a delegate and know how to schedule that work by queuing messages into the GUI's message queue. These are then picked up by the message loop and dispatched.

Example 1 is a typical Windows GUI message loop. An equivalent loop is carried out by WPF's Dispatcher.Run method, which gets called automatically when you call Application.Run to start up your application.

MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
}

Example 1: A typical Windows GUI message loop in Win32 (the "message pump").

This message loop is responsible for invoking event-processing code. In WPF, for example, this involves routing events to the framework elements listening for it, and invoking the registered user-defined code. (WPF's event subsystem is feature-rich and uses multiple models for event delivery. Regardless, all event delegates are invoked from the UI thread.)

If the UI thread is busy, incoming events back up in the queue until the thread finds time to check and respond to new messages. Figure 2 presents an example application timeline of event processing, where the x-axis is time and the y-axis is the size of the message queue. When a user or system initiates an event, that event is placed in the queue. Each event is assigned a number, so you can track it through the execution, and has a processing time label (in seconds).

[Click image to view at full size]

Figure 2: Example timeline of UI event processing.

Notice that at time 6 in Figure 2, event #9 arrives in the queue. Imagine that this were a crucial event, such as a user trying to close the window. The message loop is busy processing event #5, whose processing time is six seconds, and thus can't respond immediately. Unbeknownst to the user, it won't be done until time 10. Unfortunately, even when it finishes processing event #5, it still has to deal with the three messages (#6-#8) that arrived before #9; thus the close event isn't even processed until time 12. The user had to wait for 6 seconds before his close request was even seen by the program! Events #11 and #12 could have well been additional attempts to close the window out of frustration. Events #6-#8 might have been requests to repaint the screen because it was moved, which were entirely ignored.

Windows responds to these situations in a number of ways. If a message sits in the queue for five or more seconds, the next message changes the title bar from "App Title" to "App Title (Not Responding)." This status is reflected in tools like Task Manager. Failure to paint the screen can cause all types of visual artifacts, but most commonly this manifests as a blank window and the window's icon changing to a generic-looking window. Users usually respond by killing the process.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.