2009-10-15 4 views
3

J'essaie de rendre un objet basé sur WPF en tant que PNG dans un gestionnaire d'image ASP.NET. Nous avons créé un concepteur dans WPF qui crée des modèles basés sur XAML. L'utilisation du sérialiseur XAML pour stocker les modèles sur le disque est simple. Extraire ces mêmes objets basés sur XAML sérialisés et les reconstituer dans un gestionnaire HTTP ASP.NET s'est révélé difficile.Rendu d'objets WPF en tant qu'image dans ASP.NET

Le processus de désérialisation XAML doit s'exécuter sur un thread STA. Créer un fil de discussion et le définir sur STA et effectuer la désérialisation et la composition de l'image a fonctionné, la première fois. Je reçois l'image reconstituée basée sur XAML créée, transmise et envoyée au navigateur. Les appels suivants au gestionnaire HTTP plantent le serveur Web avec "Le thread appelant ne peut pas accéder à cet objet car un thread différent le possède".

Existe-t-il des bibliothèques permettant de générer une image à partir d'un simple objet basé sur XAML?

Répondre

0

Avez-vous envisagé de créer une application shell WPF qui charge uniquement les modèles que vous avez créés, les capture à l'écran, puis enregistre la capture d'écran sur le disque? Autorisez ensuite l'application à accepter les arguments de la ligne de commande et à transmettre le modèle que vous voulez qu'elle affiche et le nom du fichier que vous souhaitez générer.

Votre application Web pourrait alors simplement l'extraire en tant que processus séparé, attendre qu'elle se termine et récupérer le fichier. De cette façon, vous n'aurez pas à vous soucier de l'exécution de plusieurs threads STA.

2

J'avais répondu à cela il y a quelque temps on the MSDN forums, mais je vais copier cela et modifier ici pour la propostabilité de StackOverflow. :)

L'approche la plus simple consiste à faire tourner un nouveau thread STA à chaque fois, en laissant une seule image de processus, puis le thread se termine et tout est nettoyé. Cela ne sera pas vraiment à l'échelle si bien que les coûts de démarrage pour le thread ainsi que toute la configuration de l'infrastructure WPF Dispatcher ajoutera des frais généraux évidents. Vous voudriez envisager de disposer d'un pool de threads de rendu prêts à l'emploi. Vous devriez être capable de faire tourner des threads qui appellent simplement Dispatcher :: Run, et les laisser assis là. Lorsqu'un travail arrive, vous sortez un thread du pool et appelez Invoke sur l'instance Dispatcher associée (vous pouvez l'obtenir en appelant Dispatcher :: FromThread) en passant un délégué contenant toute la logique de rendu que vous voulez exécuter dans le contexte de ce fil. Lorsque cela se termine, le thread reste en cours d'exécution en raison de l'appel de Disptacher :: Run que vous avez effectué précédemment et vous pouvez le renvoyer au pool pour le prochain travail à utiliser. Pour nettoyer les threads, allez-y et appelez Dispatcher :: InvokeShutdown.

+0

Merci Drew. J'utilise un thread STA dans une configuration simple comme vous l'avez décrit. Je vais chercher à avoir un pool de threads de rendu prêts à exploiter les emplois. – KenBobPDX

+0

Oui, si vous espérez changer d'échelle, c'est un must absolu. Bonne chance! :) –

+1

Merci encore Drew. Pouvez-vous me montrer des exemples d'un tel pool de threads? Je suis un peu néophyte quand il s'agit de gérer les pools de threads. J'apprécie vraiment votre aide. – KenBobPDX

2

J'ai un exemple de code in an answer to a similar question. Bien que, comme Drew l'a souligné, vous feriez mieux de réutiliser vos discussions en leur passant des délégués. Aussi je pense que vous pourriez utiliser XamlReader.Parse() au lieu de la création programmatique.

+0

J'utilise XamlReader.Parse() pour des parties du modèle dans une collection observable. Excellent exemple. Merci beaucoup! – KenBobPDX

+0

Votez-moi maintenant! :) – RandomEngy

Questions connexes