2015-09-15 13 views
5

Sto tentando di ospitare un controllo in un thread in background, in modo che possa mostrare un'animazione a 60 FPS costanti, anche se il thread dell'interfaccia utente viene bloccato. Questo ha funzionato perfettamente in Windows 8.1, ma dal momento che l'aggiornamento a Windows 10 ora non riesce.Perché non riesco ad ottenere un'animazione FPS a 60 gradi in un'applicazione WPF quando si esegue un controllo in un thread in background in Windows 10?

Agganciare l'evento CompositionTarget.Rendering dal thread in background che ospita il controllo, in modo che l'animazione possa essere sincronizzata con l'aggiornamento del monitor. Ma sembra che non appena qualcosa nel thread dell'interfaccia utente si agganci all'evento di rendering, i frame vengono saltati ogni volta che viene visualizzata un'immagine ospitata nel thread dell'interfaccia utente principale.

È possibile visualizzare visivamente i frame ignorati e, in base al RenderTime esposto nella classe RenderingEventArgs, conferma che i frame vengono saltati, poiché il delta temporale dall'ultimo frame è di circa 33ms anziché di 16ms ogni volta che si verifica un salto di frame.

Il salto può essere indotto agganciando l'evento CompositionTarget.Rendering nel thread dell'interfaccia utente e non facendo nulla nel gestore di eventi o avviando un'animazione dello storyboard, che immagino sia perché le animazioni dello storyboard agganciano l'evento CompositionTarget.Rendering per ottenere animazione fluida.

Qui è un progetto semplice esempio che dimostra il problema:

SmoothAnimationTest.zip

ho provato sia in Windows 8.1 e Windows 10 su più macchine, in tutti i casi di Windows 8.1 viene eseguito perfettamente con il ' Controllo del Thread personale in esecuzione a 60 FPS, a prescindere da cosa. In Windows 10, 'Show Judder 1' riduce il framerate a 30 FPS costanti e 'Show Judder 2' fa sì che il framerate cambi in modo irregolare tra 30 e 60 FPS, con una media di 45-50.

In Windows 8.1 e Windows 10, premendo il pulsante "Blocca thread UI" si ottengono 60 FPS uniformi nel controllo thread separato.

Una soluzione sarebbe avere l'animazione eseguita nel thread dell'interfaccia utente e rimuovere tutti i codici di blocco da quel thread, sfortunatamente questo non è un compito semplice in quanto l'applicazione su cui sto lavorando è complessa e ci sono molti posti dove l'interfaccia utente può bloccare per più di pochi millisecondi, il che può causare un errore nell'animazione.

+1

Non riesco a scaricare il progetto di esempio come sono su una rete con proxy. Cosa intendi per "ospitare un controllo in un thread in background"? –

+2

Sembra che la tua applicazione sia indietro.È necessaria l'interfaccia utente sul thread principale e qualsiasi processo a esecuzione prolungata in grado di bloccare l'interfaccia utente viene eseguito su thread in background. –

+0

Uso HostVisual per contenere un controllo personalizzato in un thread in background [collegamento] (http://blogs.msdn.com/b/dwayneneed/archive/2007/04/26/multithreaded-ui-hostvisual.aspx) –

risposta

0

Questa potrebbe non essere una risposta completa, ma ho pensato fosse meglio non scriverlo come commento.

Per prima cosa, avete verificato che il problema non è con .Net 4.6? Vinci 10 navi con .Net 4.6 che sostituisce .Net 4.5 fornito con Win 8.1. .Net 4.6 contiene un bel po 'di modifiche interne e nuovi bug. Installerei .Net 4.6 su Win 8.1 per verificare questo come il mio primo passo ... (se il bug è con .Net 4.6 allora devi segnalarlo tramite Connect, ma non ti illuderti. anni per il bug da correggere, se non del tutto)

In secondo luogo, non so esattamente come si mostra il proprio controllo, ma sembra che sia necessario un second dispatcher. Ciò richiederà tuttavia un'altra finestra. In questo modo, qualunque cosa accada nella finestra principale, non influenzerà la finestra secondaria.

Come ho detto, non so se questa opzione è fattibile nel tuo scenario. Forse rendere la seconda finestra senza bordi, in primo piano e sovrapposta alla prima finestra ...