¿Qué hace que Windows se bloquee en esta aplicación de cinta de WPF?

Hemos tenido algunos problemas con una aplicación de escritorio bastante grande y compleja donde el uso de Microsoft Ribbon para WPF (o una combinación de elementos conectados a esto) hace que la computadora se bloquee.

El código resumido a continuación parece desencadenar una situación de bloqueo de Windows en varios equipos. Algunas computadoras experimentarán este bloqueo cada vez, algunas nunca lo experimentarán. El bloqueo se bloqueará en toda la sesión (incluidos el bloqueo numérico y el bloqueo de mayúsculas), pero en otras, el mouse seguirá moviéndose (el bloqueo numérico aún no está en funcionamiento). Cuando la computadora deja de responder, parece que cosas como el inicio de sesión remoto y el uso compartido de la red aún funcionan, pero no es posible finalizar la sesión de la consola.

En resumen, lo que parece ser la causa raíz del comportamiento es la combinación de algunas cosas:

Microsoft Ribbon para WPFAplicación de Windows Forms que aloja el control WPF en un ElementHostEl uso de formularios de Windows con doble búfer (mediante el uso de CreateParams)El uso de software de renderizado en la cinta WPF

Más tarde hemos resuelto este problema utilizandoWS_EX_COMPOSITED solo en algunos formularios seleccionados, pero me gustaría mucho descubrir la causa raíz de este problema.

Todavía tengo que descubrir una forma directa de reproducir el bloqueo, pero esta aplicación mínima parece hacer el trabajo, al menos en algunas máquinas, haciendo un poco de maximizar / restaurar y colocando el mouse sobre el botón de la cinta.

El siguiente código se compila como x86 .NET 4.0, contra elCinta de Microsoft WPF Biblioteca .NET 4.0.

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());
        }
    }
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta