Domanda

... o ...

" Quale male nelle profondità di WPF ho risvegliato? "

Sto creando un Canvas su un thread in background e lo sto trasformando in bitmap. Lavoro in codice di produzione da oltre un anno ormai senza problemi. Faccio quanto segue:

  • crea un oggetto Canvas
  • crea un nuovo oggetto NameScope
  • assegna quel NameScope al Canvas
  • disegna quello che voglio sulla tela
  • chiama canvas.Measure () con le dimensioni della tela
  • chiama canvas.Arrage () con il rettangolo disponibile di Canvas
  • chiama canvas.UpdateLayout ()
  • visualizza la tela

Nella fase di disegno, ho sempre chiamato canvas.Children.Add () per mettere UIElements sulla tela. Questo ha sempre funzionato.

Ora, per qualche motivo inspiegabile, in un caso specifico dell'applicazione a cui sto lavorando, la chiamata a canvas.Children.Add () si blocca indefinitamente, bloccando il mio thread in background. Non riesco a pensare a qualcosa che sto facendo diversamente tra il codice che funziona da oltre un anno e questo caso specifico.

Qualcuno può suggerire possibili motivi per cui una chiamata a canvas.Children.Add () si bloccherebbe in questo modo?

Modifica : il thread in background è un thread STA (il modello di elaborazione del thread in background è stato messo in atto perché non è stato possibile elaborare le immagini utilizzando WPF su un thread MTA), quindi il modello dell'appartamento del thread non dovrebbe essere il colpevole.

Modifica n. 2 : mentre capisco perché le persone suggeriscono di provare Dispatcher.BeginInvoke () dal mio thread in background, questa opzione non mi piace per due motivi:

  1. Voglio che la mia elaborazione del thread in background sia sincrona su quel thread. Il mio thread in background ha una coda a cui altri thread inviano lavori immagine e il mio thread in background elabora ogni processo man mano che arriva a loro. L'uso di Dispatcher.BeginInvoke () aggiunge un altro livello di complessità che preferirei evitare.
  2. Non ho mai necessario fino ad ora. Fare questa elaborazione in background in modo sincrono sul mio thread in background ha semplicemente funzionato . Sto cercando di determinare cosa potrebbe esserci di diverso in questo bizzarro caso limite che impedisce a questo codice di funzionare. Se non riesco a farlo funzionare, finirò per riscrivere questo codice di elaborazione senza WPF, che preferirei anche evitare.
È stato utile?

Soluzione

Quale modello di appartamento stai usando per il tuo thread in background?

Credo che WPF debba funzionare sul thread STA. Quando si genera il thread in background, provare le impostazioni è appartamento a STA.

Aggiornamento:

Se il filo STA non è il problema, allora proverei a spezzare la tela in pezzi. Fondamentalmente se si esegue un:

Dispatcher.BeginInvoke (...)

dal thread, il delegato fornito viene inserito nella parte posteriore della coda del dispatcher, consentendo l'esecuzione di altre attività in coda.

Aggiornamento 2:

Puoi anche provare a eseguire il debug nel codice sorgente per l'oggetto Canvas usando le fonti di riferimento del framework .NET. Puoi abilitare questa opzione attivando " abilita stepping di origine del framework .net " nelle opzioni di debug in Strumenti- > Opzioni.

Altri suggerimenti

Prova a chiamare Dispatcher.Run () nel thread in background.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top