我正在尝试将基于WPF的对象渲染为ASP.NET图像处理程序中的PNG。我们在WPF中创建了一个创建基于XAML的模板的设计器。使用XAML序列化程序将模板存储在磁盘上很简单。拉出那些相同的基于序列化XAML的对象并在ASP.NET HTTP处理程序中重构它们已经证明是困难的。
XAML反序列化过程需要在STA线程上运行。第一次创建一个线程并将其设置为STA并进行反序列化和图像合成。我得到了重构的基于XAML的图像创建,传回并发送到浏览器。 对HTTP处理程序的后续调用使Web服务器崩溃,“调用线程无法访问此对象,因为另一个线程拥有它。”
是否有任何库可以从简单的基于XAML的对象生成图像?
答案 0 :(得分:2)
我刚刚回答了这个问题on the MSDN forums,但我会复制一下并在这里调整以获得StackOverflow的优点。 :)
最简单的方法是每次都启动一个新的STA线程,让它处理一个图像然后线程终止并清除所有内容。虽然线程的启动成本以及所有WPF Dispatcher基础架构设置都会增加明显的开销,但这并不会真正扩展。您可能希望查看具有渲染就绪线程的池,以便将作业存储到其中。你应该能够基本上启动那些只调用Dispatcher :: Run的线程,并让它们坐在那里。当一个作业进来时,你基本上把一个线程拉出池并在相关的Dispatcher实例上调用Invoke(你可以通过调用Dispatcher :: FromThread来调用它),传递一个包含你要在该线程的上下文。完成后,线程将保持运行,因为您之前发出的Disptacher :: Run调用,您可以将其返回到池中以供下一个作业使用。要清理线程,只需转到它们并调用Dispatcher :: InvokeShutdown。
答案 1 :(得分:2)
我有一些示例代码in an answer to a similar question。虽然正如Drew指出的那样,通过将委托传递给他们,你可能会更好地重新使用你的线程。此外,我认为您可以使用XamlReader.Parse()
而不是程序化创建。
答案 2 :(得分:0)
您是否考虑过创建一个WPF shell应用程序,它只加载您创建的模板,屏幕截图,然后将屏幕截图保存到磁盘?然后允许应用程序接受命令行参数并传入您希望它呈现的模板以及您希望它生成的文件的名称。
然后,您的网络应用可以将其作为单独的进程旋转,等待它完成,然后获取文件。这样您就不必担心运行多个STA线程了。