WPF Render Thread Failures


A common problem developers face with WPF applications is how to deal with exceptions related to render thread failures. You might get reports from users indicating their application throws an exception like one of the following.

System.Runtime.InteropServices.COMException: UCEERR_RENDERTHREADFAILURE (Exception from HRESULT: 0x88980406)
   at System.Windows.Media.Composition.DUCE.Channel.SyncFlush()
   at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean enableRenderTarget, Nullable`1 channelSet)
   at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean enableRenderTarget)
   at System.Windows.Interop.HwndTarget.UpdateWindowPos(IntPtr lParam)
   at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
  
  
System.InvalidOperationException: An unspecified error occurred on the render thread.
   at System.Windows.Media.MediaContext.NotifyPartitionIsZombie(Int32 failureCode)
   at System.Windows.Media.MediaContext.NotifyChannelMessage()
   at System.Windows.Interop.HwndTarget.HandleMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
  

System.OutOfMemoryException: Insufficient memory to continue the execution of the program.
   at System.Windows.Media.MediaContext.NotifyPartitionIsZombie(Int32 failureCode)
   at System.Windows.Media.MediaContext.NotifyChannelMessage()
   at System.Windows.Interop.HwndTarget.HandleMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()

 

You might be asking why these exceptions occur, how you can prevent them from occurring, and if these are bugs that Microsoft just doesn’t bother fixing. This blog will hopefully answer these questions.

First, what is the WPF render thread and how does it differ from the UI thread?

Each WPF application may have one or more UI threads, each of which would be running its own message pump (Dispatcher.Run). Each UI thread is responsible for processing window messages from the thread’s message queue and dispatching them appropriately to windows owned by that thread. Each WPF application has just one render thread. This is a separate thread that communicates with DirectX/D3D (and/or GDI, if the software rendering pipeline is being used). For WPF content, each UI thread sends detailed instructions to the render thread on what to draw. The render thread then takes those instructions and renders the content.

So why does an application encounter an exception like the one mentioned above?

The simple answer is that the WPF render thread encountered some fatal error. There can be many causes of fatal errors on the render thread. Most of the time, a failure occurs when calling into DirectX/D3D, but can also occur due to a failed User32 or GDI call. There is no one root bug or issue for why these can occur, so there’s no one specific “fix” that can be done to alleviate the problem. When WPF’s render thread makes a call into another component; such as DirectX/D3D, User32, GDI32, etc. it checks the return value for success or failure. When a failure is detected, WPF “zombies” the render partition and notifies the UI thread of the failure the next time the two threads are synchronized. The render thread will attempt to map the failure it receives to an appropriate managed exception. For example, if the WPF render thread failed due to some out of memory condition, then it will map the failure to a System.OutOfMemoryException, and that would be the exception encountered on the UI thread. The render thread only synchronizes with the UI thread in a few locations, so the callstacks above are typically where you notice the problem, not where it actually occurred. The most common locations when they synchronize are when a window’s settings are updated (size, position, etc.) or as a result of the UI thread handling a “channel” message from DirectX.

Due to the design, unfortunately, the exception and callstack you see on the UI thread aren’t typically helpful in diagnosing the true cause of the problem. This is because by the time the exception is thrown, it is already after the point of failure on the render thread. By this time, critical state has been lost on the render thread that would help us understand where and why the failure occurred. Unfortunately, this makes it practically impossible for someone writing a WPF application to know why the failure occurred or how to avoid it. Even for us at Microsoft, it’s only slightly better to debug this in a post mortem user dump file. The render thread keeps a circular buffer of the failing call stack, which we can reconstruct internally by means of a proprietary debugger extension and private debug symbols to show the approximate original point of failure. Even then, we still don’t have access to critical state, such as locals, stack variables, and heap objects at the time; so we generally have to run the application again, looking for failures on the calls we suspect are involved.

What are some common reasons for failure?

Historically speaking, the most common bucket of WPF render thread failures was associated with video hardware or driver problems. This is particularly true on the Windows XP and 2003 platforms, where the video hardware/drivers in use (particularly in enterprise environments) weren’t up to par for hardware rendering. When WPF, via DirectX, queried the video driver for capabilities, the driver might misreport its capabilities, causing WPF to take a code path that ends up causing some DirectX / D3D failure. Or, perhaps the driver didn’t misreport its capabilities, but they just weren’t implemented well. Regardless, the majority of XP/2003 related render thread failures was due to WPF attempting to utilize the hardware rendering pipeline which ended up exposing some flaw in the driver. Even on more modern versions of Windows, this can still happen, it’s just not as common as it used to be. This is why one of our first suggestions for testing and/or working around a render thread failure is to try disabling hardware acceleration in WPF.

Another common reason we might see render thread failures is due to the use of layered windows, particularly in Windows XP / 2003. Much of the layered windows implementation in XP is fragile, to say the least, with a number of bugs that impacted WPF significantly. These problems are most often exposed when you enable the Window.AllowsTransparency or Popup.AllowsTransparency properties in WPF, which will cause layered windows to be used. Starting in Windows Vista, most of the layered window problems in Windows have been addressed with the introduction of the Desktop Window Manager (DWM).

If a render thread failure manifests as a System.OutOfMemoryException, then the likelihood is that the render thread was a victim of the process exhausting some resource. The usual circumstance is that the render thread called into some Win32/DX API, which attempted to allocate some resource, but failed. WPF checks the return value and if we get E_OUTOFMEMORY or ERROR_NOT_ENOUGH_MEMORY, will map the failure to a System.OutOfMemoryException. The exhausted resource is most often available/contiguous virtual address space (especially in 32-bit processes), but could be another resource; such as User or GDI object handles. Note that this type of problem may manifest elsewhere outside of the WPF render thread. It might be a situation where sometimes the WPF render thread is the victim of the resource exhaustion, and sometimes failures occur in other places, such as custom .Net or native allocations in other components running in process.

Some General Recommendations

1. Update your video drivers, and/or try different video hardware in the problem machine(s).

2. Disable Hardware rendering. As a quick test, you can use the DisableHWAcceleration registry value discussed here. You would set the value to 1 in order to disable WPF’s hardware rendering pipeline. Note that this affects all WPF applications running in that user’s session, so be advised you might be impacting more than one application. There are other options for disabling hardware acceleration at a more granular level. Starting in .Net 3.5, you can disable it programmatically on a per-window basis by using the HwndTarget.RenderMode property. Starting in .Net 4.0, you can disable it programmatically on a per-process basis by using the RenderOptions.ProcessRenderMode property. 

3. Upgrade to the latest version and service pack level of the .Net Framework available for your target platform. 

4. Disable the use of Windows.AllowsTransparency and Popup.AllowsTransparency in your application.

5. If you are on Windows XP or Windows 2003, test on a newer operating system, and upgrade if possible.

6. If System.OutOfMemoryExceptions are being reported, then monitor the process’s memory usage in Performance Monitor; particularly the Process\Virtual Bytes, Process\Private Bytes, and .NET CLR Memory\# Bytes in All Heaps counters. Also monitor the User Objects and GDI Objects for the process in Windows Task Manager. If you can determine that a specific resource is being exhausted, then troubleshoot the application to fix whatever is causing that resource consumption. Ultimately that should resolve the System.OutOfMemoryException.

7. If you have a reproducible scenario that can demonstrated across platforms or on different video hardware/driver combinations, it’s possible you might have stumbled across some WPF bug. In that case, please file a bug on the Connect site at http://connect.microsoft.com/VisualStudio.


Comments (6)

  1. jschroedl says:

    This is a very good writeup and as someone maintaining and enhancing a large WPF application, I appreciate the effort. In my experience, when we're out of memory (due to many windows needing WriteableBitmaps), the failure is manifested in a stack topped with these calls:

    System.Windows.Media.Composition.DUCE.Channel.SyncFlush().

    System.Windows.Media.MediaContext.CompleteRender()

    System.Windows.Interop.HwndTarget.OnResize()

    . . .

    So you explanation makes a lot of sense and helps complete my understanding of what's happening.

    We disabled h/w rendering long ago and it really feels like we're not getting the full benefit of WPF. Now that we have dropped XP support, it may be time to try turning it back on.

    A question: In our efforts to not run out of memory due to our many WriteableBitmap instances, long ago we added calls to GC:AddMemoryPressure() near where we allocate our WriteableBitmaps.  ex.

    size_t memSize = width*height*bpp*pressureMultiplier;

    CLR::GC::AddMemoryPressure(memSize);   // yes, we have a WPF application written with C++/CLI

    Is this just wasted effort or can this truly help us avoid out of memory situations emanating from the Win32/GDI/DX world?

    Also, are there any WPF-specific perf counters we can monitor?  ex. after creating a number of windows, we see things like menus and other processing time slow down significantly but profiling has not revealed the cause.

    Thanks again for the detailed write up. More please!

    John

  2. lzptimeless says:

    Visual studio 2013 was very weak on my PC, it crash with UCEERR_RENDERTHREADFAILURE usualy, it may crash when i do every thing like add new file or add new project or edit code etc. And after it crash once, it must crash when i reopen it except i reboot system.

    It seems the 2013 version not compatible with my PC, i use window8.1, AMD Phenom II 955 CPU, HD6790 graphic card with the latest dirver. Who can help me?

  3. Karel says:

    I appreciate that somebody shed some light on nature of these issues. It didn't really help me, but at least I understand more what is happening.

    Thank you Keith.

  4. John McGinty says:

    I had the same problem and it would only manifest on certain tablets with certain video drivers.

    I tracked the crash down to setting RenderOptions.BitmapScalingMode=HighQuality on the Image control.

    Setting RenderOptions.BitmapScalingMode=LowQuality fixed the problem.

  5. tata says:

    Hi a got a error message saying:

    System.Windows.Threading.Dsipatcher

    System.NullReference.Exceptions.Object reference not set to an instance of an Object.

     at System.Windows.Window.CloseWindowFromWmClose0

     at System.Windows.Window.WmClose0

     at System.Windows.Window.WindowFilterMessage(IntPtr hwnd,Int32msg.IntPtr wParam. IntPtr lParam.Boolean & handled)

    Any one can help me out please. thank you

  6. Can be reproduced by making window transparent then run following on window… or running WPF windows from with transparency in VS 2013 simulator.

                   bool ForceSoftwareRendering = true;

                   if (ForceSoftwareRendering)

                   {

                       HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;

                       HwndTarget hwndTarget = hwndSource.CompositionTarget;

                       hwndTarget.RenderMode = RenderMode.SoftwareOnly;

                   }

                   this.Width = 500;

    An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in PresentationCore.dll

    Additional information: UCEERR_RENDERTHREADFAILURE (Exception from HRESULT: 0x88980406)

    System.Runtime.InteropServices.COMException was unhandled

     HResult=-2003303418

     Message=UCEERR_RENDERTHREADFAILURE (Exception from HRESULT: 0x88980406)

     Source=PresentationCore

     ErrorCode=-2003303418

     StackTrace:

          at System.Windows.Media.Composition.DUCE.Channel.SyncFlush()

          at System.Windows.Media.MediaContext.CompleteRender()

          at System.Windows.Interop.HwndTarget.OnResize()

          at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)

          at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)

          at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)

          at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)

          at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)

          at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

          at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)

          at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)

     InnerException:

    SOLUTION NOT KNOWN YET FOR EMULATOR 😀

Skip to main content