Frage

Ich habe hier einen schweren Kopf-Scratcher auf meine Hände bekam. Ich unter Performance-Problemen mit einer WPF-Komponente in unserer Anwendung.

Unsere .net-Anwendung ist sehr groß, und fast ausschließlich in Windows Forms. Im Rahmen einer neuen Initiative umschrieb wir einen unserer Kernkomponenten mit einem reichen WPF ui. Es gibt eine Menge von WinForms <->. WPF Interop auf dem Gehen mit dieser Sache zusammen zu kleben, und ich vermute, dass in Beziehung gesetzt wird irgendwie kann, was ich sehe

Wenn ich den langsamen Betrieb in ANTS Profiler Profil sehe ich eine Menge von Aktivitäten innerhalb der Funktion auftretenden UnsafeNativeMethods.IntGetMessageW. ANTS Berichte so viel CPU-Aktivität geht es, wie es für alle unsere Geschäftslogik macht und wpf kombiniert Rendering-Zeug. Es gibt keinen Code Downline diese Funktion verwaltet wird, die die Zyklen verwendet, so was IntGetMessageW tut es das, was ich bin nach.

Ich bin nicht besonders in win32 Programmierung sehr versiert, aber ich kenne die Grundlagen eine Nachrichtenschleife in diesem Zusammenhang. Nichts von dem was ich sehe hier allerdings ist alles, was wir manuell tun - zu keinem Zeitpunkt in unserem Code sind wir direkt entweder mit dem die Interaktion selbst zugrunde liegenden MessageLoop oder jede der komplizierteren Sachen, die auf dem WPF-Dispatcher zugegriffen werden kann.

Unser WPF Komponente in Frage hier geschrieben wird, von Fenstern zu erben (dh. Es ist nicht nur ein Steuer- / Usercontrol), und wir zeigen es Showdialog aus unserer höheren Ebene Logik, die verwendeten Showdialog auf der alten WinForms-Version diesen anrufen Komponente. Es gibt einige WindowsFormsIntegrationHost Kontrollen, dass wir innerhalb der WPF der Kompatibilität der Komponenten zu erhalten mit einigen unseren bestehenden Stücken verwendet werden, die nicht in WPF neu geschrieben werden können.

Ich habe seit Tagen die Erforschung dieser, haben aber nie eine ganze Menge zu gehen gefunden. Ich halte vagee verwandte Nachrichten zu finden, dass das Gerede über Eingabenachricht (Maus und Tastatur), aber ich weiß nicht, was ich tun kann, dass überprüfen; Ich habe bereits versucht, den Code schlachten jede Maus / Tastatur zu entfernen, ich konnte.

Ich habe eine harte Zeit, die überall in erster Linie bekommen, weil diese Zeile Code vollständig isoliert ist (nicht einen Elternteil oder Kind alles, was ich wirklich kann darauf hinweisen, wie aus unserem Code kommen), und völlig undurchsichtig, was es tut.

Hier ist ein Bild von einem ANTS Aufrufdiagramm der Showdialog-Funktion des Pfad der Anrufe angezeigt zu bekommen: alt text

Ich weiß, voll, dass dies etwas sein könnte, das hat nur im Rahmen von WPF zu tun (obwohl anderen componenets haben wir in WPF geschrieben dieses Verhalten nicht angezeigt werden), oder, dass dies nur ein sehr seltsamen Fehler in ANTS Profiler , aber an diesem Punkt muss ich es eine oder andere Weise zu überprüfen. Wenn jemand kann mir sagen, was ist oder vielleicht hier gehen -. Oder mich auf irgendeine Weise verweise ich wäre in der Lage es aus mich Figur, werde ich alle Arten von guten Karma Weg direkt

UPDATE: Als Antwort unten zu einigen Diskussionen, hier ist eine andere Ansicht von ANTS - diese besser illustriert die Verwirrung das ich habe, (dies ist mit der ANTS in „CPU-Zeit“ Modus anzuzeigen). Ich habe in aller Eile Teile unseres Code zensiert, aber keine der systembezogenen Funktionen:

alt text

Danke für das Schauen!

War es hilfreich?

Lösung

fand ich diese während für Informationen zum gleichen Thema zu suchen. Ich will hinzufügen, was ich weiß und sehen, ob es hilft:

Ich bin auf einem WinXP-Box läuft - das WPF Framework ist in Vista und Win7 mehr integriert als in XP ist. Ein Teil davon könnte darauf zurückzuführen sein, wie WPF läuft „on top“ des XP-Desktop, anstatt in sie.

Ich bin eine reine natives WPF-Anwendung ausgeführt -. Ohne WinForms oder anderem Code

ich in diesen lief einfach versuchen, um festzustellen, warum ein Fenster scrollen würde verbrauchen 100% CPU und Stottern während es zu tun.

Ausführen der AQtime Performance Profiler, ich sehe, dass IntGetMessageW den größten Teil dieser 100% CPU-Auslastung belegt. Dies ist nicht wegen IntGetMessageW für eine Nachricht wartet, aber etwas die Funktion tatsächlich tun.

Das einzige, was ich in noch nicht ausgesehen haben, ist, dass vielleicht IntGetMessageW Noch nie war eine schnelle Methode, und vielleicht einfach WPF übermäßigen Einsatzes es. Es ist möglich, dass Datenbindungen in WPF verwenden, um die nativen Win32-Pumpe Nachricht Abhängigkeitseigenschaften in WPF zu aktualisieren. Wenn das der Fall ist, könnte es sein, dass mein Fenster einfach zu viele Bindungen hat.

Andere Tipps

Ja, das ist normal. Alle GUI-Anwendung ist immer Ausführen GetMessageW () wartet für Windows es eine Nachricht zu senden. Es ist eigentlich nicht CPU-Zyklen tut dies Brennen, nur auf einem internen Synchronisationsobjekt blockiert, bis eine Art von UI-Ereignisse signalisiert wird.

Das macht natürlich Profilierungs UI apps schwierig, die Sie wirklich benötigen Unit-Tests, dass Test die Subkomponenten Ihrer Anwendung.

Wenn Sie eine Anwendung Profilierung, müssen Sie zwischen unterscheiden Zeit damit verbracht in einem Verfahren und einer CPU-Zyklen verbraucht. Viele Profilierwerkzeuge zeigen Ihnen die Gesamtzeit in einem Verfahren verbracht - die im Falle von wie GetMessageW somthing wird ziemlich hoch sein. Alle von der Aktivität des Hauptthreads einer GUI-Anwendung erscheinen in diesem Verfahren geschehen. Das ist nicht unbedingt ein Problem, aber ... dies einfach das Hauptnachrichtensystem sein kann auf einem Synchronisationsobjekt warten und nicht wirklich raubend Zyklen.

Ich würde Sie mit der Sampling-Funktion in den ANTS Profiler starten schlägt die Methoden zu identifizieren, die aufgerufen werden am häufigsten und korrelieren, die zu den Methoden, die die meisten CPU-Zyklen verbrauchen. Wenn Sie das getan haben, entscheiden Sie, wo Sie Instrument, um Ihre Anwendung zu tauchen weiter und bekommen eine Vorstellung davon, was die Anrufgraphen sehen aus wie für die Orte, die die meisten CPU-intensiv sind.

Sie sollen zuerst Ihren eigenen Code durch den Verdacht starten. Es ist selten, dass so etwas wie die WPF oder Win32-Infrastruktur für eine schlechte Leistung oder hohe CPU-Auslastung verantwortlich ist. Wahrscheinlich liegt das Problem irgendwo in Ihrer Implementierung -. Hilft es Ihnen, ein Gefühl von, wo CPU-Zyklen in Ihrem Programm ausgegeben werden

Ich schlage vor, dass Sie auch einige Zeit damit verbringen,

Der Call Graph ist ein weiteres nützliches Werkzeug in ANTS, wie es Ihnen in Bereiche des Codes hilft bohren, die teuersten sind. Der Schlüssel ist, um sicherzustellen, dass Sie suchen auf der Gesamtkosten und nicht nur die Gesamtzeit .

alt text

Sieht aus wie Ihre Nachricht Pumpe ist viel zu pumpen. Könnte interessant sein zu sehen, welche Art von Nachricht wird Ihre Nachrichten-Warteschlange gefüllt von. Können Sie Spy ++ auf Ihrem Fenster verwenden, um zu sehen, was los ist?

Bearbeiten

Ich habe das Problem falsch verstanden.

Hans Passant ist richtig, das Programm nur auf GetMessage wartet auf ein Ereignis zu verarbeiten.

scroll top