在不同的线程上创建路径并渲染到同一个画布

时间:2009-08-03 00:21:11

标签: c# wpf

我目前正在研究WPF(在幕后使用C#)系统,该系统需要从许多不同的文件中呈现数据。这些文件大多数是AutoCAD文档。每个文件都带有一组数据,我们需要在同一画布上在屏幕上绘制。将每个文件视为需要在屏幕上显示的潜在“图层”或叠加层。

目前,每个图形源都会被解析并转换为一组Path个对象。每个路径集合都会呈现给它自己的Canvas,以便可以打开或关闭其可见性。这些画布中的每一个都是父画布的子画面,它具有一组应用于它的变换。这些变换是基本比例和平移渲染变换,用于支持正在查看的图像的平移和缩放。

此功能目前工作正常,但速度很慢。我们在屏幕上渲染了很多Path对象,加载/创建这些Path实例需要花费很长时间。

负载速度本身并不是一个问题;真正的问题是我需要在UI线程上创建Path实例,否则我无法在同一个画布上渲染它们。因此,在加载时,整个用户界面被锁定,用户无法执行任何操作。

我在网上广泛搜索过,但似乎无法找到问题的解决方案。我偶然发现了一篇文章(遗憾的是我没有链接),它描述了在同一个窗口上托管在不同线程上创建的项目的方法。这对我来说根本不起作用。我尝试了一些我在文章中找到的东西,但我根本无法渲染任何东西。

所以我想我的问题的关键是:是否有可能在不同的线程上创建一组UI对象,特别是Path对象,然后将它们加载到主UI线程上的父画布中并让它们全部播放很好地在一起?任何参考,文章或教程将不胜感激。

我期待着你的帮助!谢谢你的阅读。

OJ

编辑1:每个Path实例只是一行颜色。它们并不复杂。但似乎创造这些物品本身就是花时间(我可能是错的)。谢谢!

3 个答案:

答案 0 :(得分:1)

一种可能性是在单独的线程上创建PathGeometry(大部分工作),冻结它,并将其设置为在UI线程上创建的Path。 (我自己没有这样做,只读过它。)

这是Freezable对象上的MSDN article,其中PathGeometry是一个,它表明一旦冻结它们就可以在线程之间共享(但不再被修改)。这可能适合您的情况,也可能不适合。

答案 1 :(得分:0)

您是否正在使用每个UIElement上存在的Dispatcher并提供BeginInvoke方法来在正确的线程上运行代码?

您是否阅读过此MSDN文章:Build More Responsive Apps With The Dispatcher

Windows Presentation Foundation线程模型描述为here

答案 2 :(得分:0)

只是一个想法。如果不使用UI对象,您可以使用XAML吗?它只是一个字符串。例如,当您的应用程序启动时,您为每个文件生成一个后台线程(BackgroundWorker)。后台工作程序读取文件并将具有画布作为根UI元素的XAML放在一起,然后将从数据生成的路径放在一起。然后,将该XAML作为字符串返回给UI线程。然后,UI线程使用XamlReader.Load方法加载XAML,并将生成的canvas对象添加到父画布。您甚至可以在工作线程上创建UI元素(子画布及其包含的路径),然后获取生成的XAML以返回到主线程。