2013-07-04 7 views
8

Wir hatten ein paar Probleme mit einer ziemlich großen und komplexen Desktop-Anwendung, wo die Verwendung von Microsoft Ribbon für WPF (oder eine Kombination von damit verbundenen Dingen) den Computer verursacht aufhängen.Was bewirkt, dass Windows in dieser WPF-Ribbon-Anwendung hängt

Der unten aufgeführte Code scheint eine Windows-Hang-Situation auf einer Reihe von Computern auszulösen. Manche Computer werden dieses Problem jedes Mal erleben, manche werden es nie erfahren. Das hängt, auf einigen Computern die gesamte Sitzung sperren (einschließlich Num-Sperre und Feststelltaste), aber in anderen, die Maus wird immer noch bewegen (Num-Sperre noch aus dem Geschäft). Wenn der Computer nicht mehr reagiert, scheint es, dass Remote-Anmeldung und Netzwerkfreigabe weiterhin funktionieren, es ist jedoch nicht möglich, die Konsolensitzung zu beenden.

Kurz gesagt, was scheint die Ursache für das Verhalten zu sein, ist die Kombination von ein paar Dinge:

  • Microsoft Ribbon für WPF
  • Windows Forms-Anwendung Hosting der WPF-Steuerelement in einem Element
  • die Verwendung von doppelt gepufferten Windows Forms (durch Verwendung von CreateParams)
  • die Verwendung von Software, die auf dem band WPF Rendering

Wir haben dieses Problem später behoben, indem wir WS_EX_COMPOSITED nur für einige ausgewählte Formulare verwenden, aber ich möchte sehr gerne die Ursache dieses Problems herausfinden.

Ich habe noch einen direkten Weg zu finden, um den Hang zu reproduzieren, aber diese minimale Anwendung scheint das Geschäft zumindest auf einigen Maschinen zu erledigen, indem Sie ein wenig maximieren/wiederherstellen und die Maus über dem Mauszeiger bewegen Menüband

Der folgende Code ist als x86 .NET 4.0, gegen die Microsoft WPF Ribbon .NET 4.0-Bibliothek kompiliert.

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

Haben Sie dieses Problem jemals gelöst? Ich konnte nur diese Frage und dieses andere http://stackoverflow.com/questions/7719627/wpf-elementhost-in-winforms-crashes-windows-when-maximized zu diesem Thema finden, aber keine hat eine Lösung gefunden. –

+0

@EduardoWada Nicht wirklich. Wie @ Olly gesagt hat, hat dies wahrscheinlich mit der Interaktion von WPF mit den Grafiktreibern zu tun. Die "Lösung" bestand darin, die 'CreateParams'-Überschreibung zu deaktivieren, und dies stattdessen für zielgerichtetere Formulare. – torkildr

Antwort

1

Überprüfen Sie, ob die Grafiktreiber auf den betroffenen Computern auf dem neuesten Stand sind. WPF funktioniert sehr anders als herkömmlicher GDI-Code, daher können manchmal unzuverlässige Treiber die Art von Problem verursachen, die Sie beschreiben.

+0

Ich denke auch, dass es Grafiktreiber verwandt sein könnte.Interessant ist, dass dies bei mehreren Grafikkartenanbietern zu geschehen scheint. Ich habe auch, wie Sie vorgeschlagen haben, versucht, auf den neuesten Grafiktreiber zu aktualisieren. – torkildr

1

Wie Sie festgestellt haben, kommt das Problem mit Composite-Windows. Ich habe das Problem weiter analysiert und es scheint ein O verwandtes Problem zu sein:

Siehe The Case of Slow WPF Rendering in a WinForms Application

zwei Threads versuchen, sich Fenster in einer Schleife zu machen und ungültig machen, wo auf einem Thread des Verbund WinForms Fenster machen und auf Der andere Thread der WPF Render-Thread macht das gleiche. Dies geschieht auf Win 7 - Win 10 Maschinen, solange Software-Rendering aktiv ist.

Es sieht wie ein DWM-Problem (Desktop Window Manager) aus, bei dem nur MS-Experten uns mitteilen können, ob WPF oder WinForms einen impliziten Vertrag verletzen oder ob es sich um einen einfachen DWM-Fehler handelt.