Question

... ou ...

"Quel mal ai-je réveillé au plus profond de WPF?"

Je crée un canevas sur un fil d’arrière-plan et le rend au format bitmap. Je travaille dans le code de production depuis plus d’un an sans problèmes. Je fais ce qui suit:

  • créer un objet Canvas
  • créer un nouvel objet NameScope
  • attribuez NameScope au canevas
  • dessiner ce que je veux sur la toile
  • appelez canvas.Measure () avec la taille du canevas
  • appelez canvas.Arrage () avec le recto disponible du canevas
  • appelez canvas.UpdateLayout ()
  • rendre le canevas

Au stade du tirage au sort, j'ai toujours appelé canevas.Children.Add () pour placer des droits UIE sur le canevas. Cela a toujours fonctionné.

Maintenant, pour une raison inexplicable, dans un cas spécifique de l'application sur laquelle je travaille, l'appel à canvas.Children.Add () se bloque indéfiniment, bloquant ainsi mon thread d'arrière-plan. Je ne vois rien de ce que je fais différemment entre le code qui fonctionne depuis plus d'un an et ce cas particulier.

Quelqu'un peut-il suggérer les raisons possibles pour lesquelles un appel à canvas.Children.Add () serait bloqué comme ceci?

Modifier : le fil d'arrière-plan est un fil STA (le modèle de traitement du fil d'arrière-plan a été mis en place car je ne pouvais pas traiter les images à l'aide de WPF sur un fil MTA). pas le coupable.

Modifier n ° 2 : je comprends pourquoi les gens suggèrent que j'essaie Dispatcher.BeginInvoke () de mon fil d'arrière-plan, mais cette option ne me plaît pas pour deux raisons:

  1. Je souhaite que le traitement de mon thread d'arrière-plan soit synchrone sur ce thread. Mon thread d'arrière-plan a une file d'attente à laquelle d'autres threads soumettent des travaux d'image, et mon thread d'arrière-plan traite chaque travail au fur et à mesure qu'il leur parvient. Utiliser Dispatcher.BeginInvoke () ajoute une autre couche de complexité que je préférerais éviter.
  2. Je n'ai jamais eu besoin de jusqu'à maintenant. Ce traitement en arrière-plan de manière synchrone sur mon thread d'arrière-plan a tout simplement fonctionné . J'essaie de déterminer ce qui pourrait éventuellement être différent de cet étrange cas qui fait que ce code ne fonctionne pas. Si je ne parviens pas à le faire fonctionner, je vais réécrire ce code de traitement sans WPF, ce que je préférerais aussi éviter.
Était-ce utile?

La solution

Quel modèle d'appartement utilisez-vous comme arrière-plan?

Je pense que WPF doit être exécuté sur le thread STA. Lorsque vous créez le fil d’arrière-plan, essayez les paramètres correspondant à STA.

Mise à jour:

Si le problème avec le thread STA n’est pas le problème, j’essaierai alors de décomposer votre canevas en morceaux. Fondamentalement, si vous faites un:

Dispatcher.BeginInvoke (...)

depuis votre thread, le délégué fourni est placé à l'arrière de la file d'attente du répartiteur, ce qui permet à d'autres tâches en attente de s'exécuter.

Mise à jour 2:

Vous pouvez également essayer de déboguer le code source de l'objet Canvas à l'aide des sources de référence du framework .NET. Vous pouvez l'activer en activant l'option "Activer le pas à pas source du cadre .net". dans les options de débogage sous Outils-> Options.

Autres conseils

Essayez d'appeler Dispatcher.Run () dans le thread d'arrière-plan.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top