Ich versuche, ein Steuerelement in einem Hintergrund-Thread zu hosten, so dass es eine Animation mit einer konstanten 60 FPS anzeigen kann, selbst wenn der UI-Thread blockiert wird. Dies funktionierte perfekt in Windows 8.1, aber seit dem Upgrade auf Windows 10 schlägt es jetzt fehl.Warum kann ich in einer WPF-Anwendung keine glatte 60 FPS-Animation erhalten, wenn ich ein Steuerelement in einem Hintergrundthread in Windows 10 ausführe?
Ich hänge das CompositionTarget.Rendering-Ereignis aus dem Hintergrund-Thread hostet das Steuerelement, so dass die Animation mit der Monitor-Aktualisierung synchronisiert werden kann. Sobald jedoch etwas im Hauptthread der Benutzeroberfläche auch an das Rendering-Ereignis angehängt wird, werden Frames immer dann übersprungen, wenn sich ein Visual im Hauptthread der Benutzeroberfläche ändert.
Ich kann visuell Frames übersprungen sehen, und entsprechend der RenderTime in der RenderingEventArgs Klasse bestätigt dies, dass Frames übersprungen werden, da das Zeitdelta seit dem letzten Frame um 33ms statt 16ms immer wenn ein Frame übersprungen wird.
Das Überspringen kann ausgelöst werden, indem das CompositionTarget.Rendering-Ereignis im UI-Thread angehängt wird und nichts im Ereignishandler oder durch Starten einer Storyboard-Animation ausgeführt wird, da Storyboard-Animationen das CompositionTarget.Rendering-Ereignis erreichen glatte Animation.
Hier ist ein einfaches Beispiel-Projekt, das das Problem veranschaulicht:
ich es in Windows 8.1 und Windows 10 auf mehreren Maschinen getestet haben, in jedem Fall von Windows 8.1 läuft perfekt mit dem " Own Thread 'Kontrolle läuft bei 60 FPS, egal was passiert. In Windows 10 reduziert "Show Judder 1" die Framerate auf konstante 30 FPS, und "Show Judder 2" bewirkt, dass die Framerate zwischen 30 und 60 FPS wechselt, was einem Durchschnitt von 45-50 entspricht.
Sowohl in Windows 8.1 als auch in Windows 10 führt das Drücken der Schaltfläche "UI-Thread blockieren" zu einem weichen 60 FPS im separaten Thread-Steuerelement.
Eine Lösung wäre, die Animation im UI-Thread laufen zu lassen und den gesamten blockierenden Code aus diesem Thread zu entfernen, leider ist dies keine einfache Aufgabe, da die Anwendung, an der ich arbeite, komplex ist und es viele Stellen gibt Die Benutzeroberfläche kann länger als einige Millisekunden blockieren, was zu einem Ruckeln in der Animation führen kann.
Ich kann das Beispielprojekt nicht herunterladen, da ich in einem Proxy-Netzwerk bin. Was meinst du mit "Host ein Steuerelement in einem Hintergrund Thread"? –
Es scheint, dass Ihre Anwendung rückwärts ist.Sie benötigen die Benutzeroberfläche für den Hauptthread und alle Prozesse mit langer Laufzeit, die die Benutzeroberfläche blockieren können, werden für Hintergrundthreads ausgeführt. –
Ich benutze HostVisual, um ein benutzerdefiniertes Steuerelement in einem Hintergrundthread zu enthalten [link] (http://blogs.msdn.com/b/dwayneneed/archive/2007/04/26/multithreaded-ui-hostvisual.aspx) –