You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: support/developer/dotnet/framework/general/wpf-render-thread-failures.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ ms.custom: sap:Common Language Runtime (CLR)
12
12
13
13
This article discusses failures in the Windows Presentation Foundation (WPF) render thread. This article focuses on exceptions that occur in `SyncFlush` or `NotifyPartitionIsZombie` and hang situations that occur in `WaitForNextMessage` or `SynchronizeChannel`.
14
14
15
-
WPF applications might have one or more UI threads that are running their own message pump (`Dispatcher.Run`). Each UI thread is responsible for processing window messages from the thread's message queue and dispatching them to windows that are owned by that thread. Each WPF application has only one render thread. This is a separate thread that communicates with Microsoft DirectX D3D (or GDI, if the software rendering pipeline is used). For WPF content, each UI thread sends detailed instructions to the render thread on what to draw. The render thread then follows those instructions to render the content.
15
+
WPF applications might have one or more UI threads that are running their own message pump (`Dispatcher.Run`). Each UI thread is responsible for processing window messages from the thread's message queue and dispatching them to windows that the thread owns. Each WPF application has only one render thread. That separate thread communicates with Microsoft DirectX D3D (or GDI, if the software rendering pipeline is used). For WPF content, each UI thread sends detailed instructions to the render thread on what to draw. The render thread then follows those instructions to render the content.
16
16
17
17
_Applies to:_ .NET Framework 4.8
18
18
@@ -61,23 +61,23 @@ The application might stop responding in `WaitForNextMessage` or `SynchronizeCha
These are symptoms of a failure in the render thread. This is a challenging problem to diagnose because the exceptions and call stacks are generic. Render thread failures generate one of the calls stacks that are listed here (or a minor variation of the call stacks) regardless of the root cause. Therefore, it can be difficult to diagnose the problem or recognize a situation in which two separate hang incidents have the same root cause.
64
+
These call stacks are symptoms of a failure in the render thread. This is a challenging problem to diagnose because the exceptions and call stacks are generic. Render thread failures generate one of the calls stacks that are listed here (or a minor variation of the call stacks) regardless of the root cause. Therefore, it can be difficult to diagnose the problem or recognize a situation in which separate incidents of non-response have the same root cause.
65
65
66
66
### Causes of the failures in SyncFlush, WaitForNextMessage, SynchronizeChannel, and NotifyPartitionIsZombie
67
67
68
68
Exceptions and situations in which the software stops responding occur in a UI thread if the WPF render thread experiences a fatal error. These errors have several possible causes, but the render thread doesn't share that information together with the UI thread. Because these errors are not related to a single root bug or issue, they have no specific solution.
69
69
70
-
WPF's render thread checks the return value for success or failure when it makes a call into another component, such as DirectX D3D, User32, or GDI32. When a failure is detected, WPF "zombies" the render partition and notifies the UI thread of the failure when the two threads are synchronized. The render thread tries to map the failure it receives to an appropriate managed exception. For example, if the WPF render thread failed because of an out-of-memory condition, it maps the failure to a `System.OutOfMemoryException`. That exception is displayed on the UI thread. The render thread synchronizes with the UI thread in only a few locations. Therefore, the call stacks that are mentioned in the previous section typically appear where you notice symptoms of the problem, not where the problem actually occurrs. Synchronization most commonly occurs in locations where a window's settings are updated (size, position, and so on) or where the UI thread handles a "channel" message from the render thread.
70
+
WPF's render thread checks the return value for success or failure when it makes a call into another component, such as DirectX D3D, User32, or GDI32. When a failure is detected, WPF "zombies" the render partition and notifies the UI thread of the failure when the two threads are synchronized. The render thread tries to map the failure it receives to an appropriate managed exception. For example, if the WPF render thread failed because of an out-of-memory condition, it maps the failure to a `System.OutOfMemoryException`. That exception is displayed on the UI thread. The render thread synchronizes with the UI thread in only a few locations. Therefore, the call stacks that are mentioned in the previous section typically appear where you notice symptoms of the problem, not where the problem actually occurs. Synchronization most commonly occurs in locations where a window's settings are updated (size, position, and so on) or where the UI thread handles a "channel" message from the render thread.
71
71
72
-
By design, the exceptions and call stacks on the UI thread aren't useful resources to help you diagnose the problem. By the time the exception is thrown, the render thread has already passed the point of failure. The render thread’s critical state would help you understand where and why the failure occurred, but it’s already lost. Because of this situation, the author of a WPF application can't know why the failure occurred or how to avoid it. Instead of analyzing exceptions and call stacks, we debug the problem in a postmortem user dump file. Although this method is only slightly more useful, the render thread keeps a circular buffer of the failing call stack. We can reconstruct the buffer internally by using a proprietary debugger extension and private debug symbols to show the approximate initial point of failure. However, we don't have access to the critical state, such as locals, stack variables, and heap objects at the time of failure. We generally run the application again to look for failures on the calls that we suspect are involved.
72
+
By design, the exceptions and call stacks on the UI thread aren't useful resources to help you diagnose the problem. By the time the exception is thrown, the render thread is already past the point of failure. The render thread’s critical state would help you understand where and why the failure occurred, but it’s already lost. Because of this situation, the author of a WPF application can't know why the failure occurred or how to avoid it. Instead of analyzing exceptions and call stacks, we debug the problem in a postmortem user dump file. Although this method is only slightly more useful, the render thread keeps a circular buffer of the failing call stack. We can reconstruct the buffer internally by using a proprietary debugger extension and private debug symbols to show the approximate initial point of failure. However, we don't have access to the critical state, such as locals, stack variables, and heap objects at the time of failure. We generally run the application again to look for failures on the calls that we suspect are involved.
73
73
74
74
## Failures with video hardware or drivers
75
75
76
-
The most common bucket of WPF render thread failures is associated with video hardware or driver problems. When WPF queries the video driver for capabilities through DirectX, the driver might misreport its capabilities. This action causes WPF to take a code path that causes some DirectX D3D failures. The driver might also be implemented incorrectly. The majority of render thread failures occur because WPF tries to use the hardware rendering pipeline in a manner that exposes some flaw in the driver. This condition might occur on modern versions of Windows that use modern graphics devices and drivers, although as commonly as it occurred in the early days of WPF. For this reason, when you start to test or work around a render thread failure, we recommend that you first disable hardware acceleration in WPF.
76
+
The most common bucket of WPF render thread failures is associated with video hardware or driver problems. When WPF queries the video driver for capabilities through DirectX, the driver might misreport its capabilities. This action causes WPF to take a code path that causes some DirectX D3D failures. The driver might also be implemented incorrectly. Most render thread failures occur because WPF tries to use the hardware rendering pipeline in a manner that exposes some flaw in the driver. This condition might occur on modern versions of Windows that use modern graphics devices and drivers, although as commonly as it occurred in the early days of WPF. For this reason, when you start to test or work around a render thread failure, we recommend that you first disable hardware acceleration in WPF.
77
77
78
78
A failure might also occur if an app requests a scene that’s too complex for the driver (or DirectX) to render. This situation isn’t common for modern drivers. However, every device has limits that can be exceeded.
79
79
80
-
Another historical source of render thread failures are the [Window.AllowsTransparency](/dotnet/api/system.windows.window.allowstransparency) or [Popup.AllowsTransparency](/dotnet/api/system.windows.controls.primitives.popup.allowstransparency) properties in WPF. These properties cause [layered windows](/windows/win32/winmsg/window-features#layered-windows) to be used. Layered windows caused problems in older versions of Windows. However, most of the problems were resolved by the introduction of the Desktop Window Manager (DWM) in Windows Vista.
80
+
Another historical source of render thread failures are the [Window.AllowsTransparency](/dotnet/api/system.windows.window.allowstransparency) or [Popup.AllowsTransparency](/dotnet/api/system.windows.controls.primitives.popup.allowstransparency) properties in WPF. These properties cause [layered windows](/windows/win32/winmsg/window-features#layered-windows) to be used. Layered windows caused problems in older versions of Windows. However, most of these problems were resolved by the introduction of the Desktop Window Manager (DWM) in Windows Vista.
81
81
82
82
If a render thread failure manifests as a `System.OutOfMemoryException`, that error typically indicates that the process exhausted some resource. In this situation, the render thread called into a `Win32/DX` API that tried unsuccessfully to allocate some resource. WPF maps return values such as `E_OUTOFMEMORY` or `ERROR_NOT_ENOUGH_MEMORY` to a `System.OutOfMemoryException`. Although the exception entry refers to "memory," this mention could refer to any kind of resource, such as GDI object handles, other system handles, GPU memory, standard RAM memory, and so on.
0 commit comments