Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What causes Windows to hang in this WPF Ribbon application

We've had a few problems with a rather large and complex desktop application where the use of Microsoft Ribbon for WPF (or a combination of things connected to this) causes the computer to hang.

The boiled down code below seems to trigger a Windows hang situation on a number of computers. Some computers will experience this hang every time, some will never experience it. The hang will, on some computer make the entire session lock up (including num lock and caps lock), but on others, the mouse will still move (num lock still out of business). When the computer becomes unresponsive, it seems things like remote logon and network sharing still works, but it is not possible to end the console session.

In short, what seems to be the root cause of the behavior is the combination of a few things:

  • Microsoft Ribbon for WPF
  • Windows Forms application hosting the WPF control in an ElementHost
  • The use of double buffered Windows Forms (by use of CreateParams)
  • The use of software rendering on the WPF ribbon

We have later solved this issue by using WS_EX_COMPOSITED only on a few selected forms, but I'd very much like to uncover the root cause of this issue.

I've yet to discover a straight forward way to reproduce the hang, but this minimal application seems to get the business done, at least on some machines, by doing a bit of maximize/restore and hovering the mouse above the ribbon button.

The following code is compiled as x86 .NET 4.0, against the Microsoft WPF Ribbon .NET 4.0 library.

using System;
using System.Windows.Forms;
using Microsoft.Windows.Controls.Ribbon;
using System.Windows.Interop;
using System.Windows.Forms.Integration;

namespace WindowsRibbonHang
{
    public class Form1 : Form
    {
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
                return cp;
            }
        }

        public Form1()
        {
            Ribbon ribbon = new Ribbon();

            RibbonTab tab = new RibbonTab { Header = "FooTab" };
            ribbon.Items.Add(tab);

            RibbonSplitButton button = new RibbonSplitButton { Label = "FooButton" };
            tab.Items.Add(button);

            ElementHost elementHost = new ElementHost
            {
                Dock = DockStyle.Fill,
                Child = ribbon,
            };

            Controls.Add(elementHost);
            Dock = DockStyle.Fill;

            ribbon.Loaded += (sender, args) => {
                HwndSource hwndSource = System.Windows.PresentationSource.FromVisual(ribbon) as HwndSource;
                HwndTarget hwndTarget = hwndSource.CompositionTarget;
                hwndTarget.RenderMode = RenderMode.SoftwareOnly;
            };
        }
    }

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
like image 797
torkildr Avatar asked Jul 04 '13 15:07

torkildr


2 Answers

Try checking that the graphics drivers on the affected computers are up-to-date. WPF works very differently from traditional GDI code, so sometimes unreliable drivers can cause the kind of problem that you describe.

like image 90
Olly Avatar answered Oct 20 '22 12:10

Olly


As you have found the problem comes with composite Windows. I have analyzed the issue further and it seems to be an OS related issue:

See The Case of Slow WPF Rendering in a WinForms Application

Two threads try to render and invalidate each other window in a loop where on one thread the composite Winforms Window renders and on the other thread the WPF render thread does the same thing. This happens on Win 7 - Win 10 machines as long as software rendering is active.

It looks like a DWM (Desktop Window Manager) issue where only the MS experts can tell us if WPF or WinForms is violating an implicit contract or if it is a plain DWM bug.

like image 22
Alois Kraus Avatar answered Oct 20 '22 11:10

Alois Kraus