Was bewirkt, dass Windows in dieser WPF-Multifunktionsleistenanwendung hängt?

Es gab einige Probleme mit einer ziemlich großen und komplexen Desktop-Anwendung, bei der die Verwendung von Microsoft Ribbon for WPF (oder einer Kombination von damit verbundenen Dingen) dazu führte, dass der Computer hängen blieb.

Der unten stehende gekochte Code scheint auf einer Reihe von Computern eine Windows-Hangsituation auszulösen. Bei einigen Computern tritt dieses Problem jedes Mal auf, bei anderen wird es nie auftreten. Durch das Aufhängen wird auf einigen Computern die gesamte Sitzung gesperrt (einschließlich Num-Taste und Feststelltaste), auf anderen wird die Maus weiter bewegt (Num-Taste ist immer noch nicht in Betrieb). Wenn der Computer nicht mehr reagiert, funktionieren scheinbar Remoteanmeldungen und die Netzwerkfreigabe weiterhin, die Konsolensitzung kann jedoch nicht beendet werden.

Kurz gesagt, die Hauptursache des Verhaltens scheint die Kombination einiger Dinge zu sein:

Microsoft Ribbon für WPFWindows Forms-Anwendung, die das WPF-Steuerelement in einem ElementHost hostetVerwendung von doppelt gepufferten Windows Forms (mithilfe von CreateParams)Die Verwendung von Software-Rendering auf dem WPF-Menüband

Wir haben dieses Problem später mithilfe von gelöstWS_EX_COMPOSITED nur auf einigen ausgewählten Formularen, aber ich würde sehr gerne die Hauptursache für dieses Problem aufdecken.

Ich habe noch keinen direkten Weg gefunden, um den Hang zu reproduzieren, aber diese minimale Anwendung scheint das Geschäft zumindest auf einigen Rechnern zu erledigen, indem Sie ein wenig maximieren / wiederherstellen und den Mauszeiger über die Multifunktionsleistenschaltfläche halten.

Der folgende Code wird als x86 .NET 4.0 gegen das kompiliertMicrosoft WPF-Multifunktionsleiste .NET 4.0-Bibliothek.

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

Antworten auf die Frage(2)

Ihre Antwort auf die Frage