Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering WPF objects as a graphic in ASP.NET

Tags:

asp.net

image

wpf

I'm trying to render a WPF based object as a PNG inside an ASP.NET image handler. We've created a designer in WPF that creates XAML based templates. Using the XAML serializer to store the templates on disk is simple. Pulling those same serialized XAML based objects and reconstituting them in an ASP.NET HTTP handler has proved difficult.

The XAML deserialization process needs to run on a STA thread. Creating a thread and setting it to STA and doing the deserialization and image composition worked, the first time. I get the reconstituted XAML based image created, passed back and sent to the browser. Subsequent calls to the HTTP handler crash the web server with "The calling thread cannot access this object because a different thread owns it."

Are there any libraries out there that will generate an image from a simple XAML based object?

like image 998
KenBobPDX Avatar asked Nov 28 '25 21:11

KenBobPDX


1 Answers

I had answered this a while ago on the MSDN forums, but I'll copy that and tweak here for the prosterity of StackOverflow. :)

The simplest approach is spinning up a new STA thread everytime, letting that process one image and then the thread terminates and everything is cleaned up. That won't really scale so great though as the spin-up costs for the thread as well as all WPF Dispatcher infrastructure setup will add obvious overhead. You would want to look into having a pool of render ready threads that you farm the jobs out to. You should be able to basically spin up threads that just call Dispatcher::Run, and leave them sitting there. When a job comes in, you basically pull a thread out of the pool and call Invoke on the associated Dispatcher instance (you can get this by calling Dispatcher::FromThread) passing a delegate that contains all the rendering logic you want to execute in the context of that thread. When that finishes, the thread will remain running, because of Disptacher::Run call you made earlier, and you can return it to the pool for the next job to use. To clean up threads, just go to them and call Dispatcher::InvokeShutdown.

like image 108
Drew Marsh Avatar answered Nov 30 '25 11:11

Drew Marsh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!