【问题标题】:Silverlight - Is it possible to create UI elements on a background thread?Silverlight - 是否可以在后台线程上创建 UI 元素?
【发布时间】:2011-08-19 01:01:40
【问题描述】:

我正在使用 PolyLineSegment 和点在 Silverlight 中构建折线图控件。它按预期工作,但是当需要可视化的数据太多(点太多)时,应用程序会冻结很长时间。出于明显的原因,我无法在单独的线程上移动我的代码 - 它直接处理 UI 元素,因此当我尝试从单独的线程调用它们时会导致异常(即使 UI 元素尚未呈现)。

有没有办法在后台线程上动态创建 UI 元素,然后将它们传递给 UI 线程进行渲染?如果没有,可能的解决方案是什么?我正在考虑创建一个位图图像而不是实际控件,但在这种情况下不会有太多交互性。

【问题讨论】:

  • 什么时间最长?是元素的实际渲染,还是在创建每个元素之前执行一堆计算?如果是后者,您可能可以在后台线程上运行这些计算,然后通过 Dispatcher 编组每个元素的创建。
  • 我的代码中没有太多的计算,而是大量的数据。我说的是百万分。缩小它们并不是最好的选择。
  • 这使它变得更加困难。但是,如果您有数百万个点,它们如何同时显示在屏幕上?即使在 1024x768 下也有
  • 这是 PCM 音频数据的图表,它基本上显示了一个波形。用于确定每个点的 {X, Y} 位置的算法依赖于相邻值。我试图缩小数组并应用插值,但视觉结果不是很准确。至于渲染时间,PolyLineSegment 好像是把所有的点都翻译成一张位图,所以没花那么多时间。
  • 根据我的经验,实际上是 PolyLineSegment 的渲染需要花费所有时间。创建 100k 点很快;渲染它们很慢。

标签: c# multithreading silverlight charts


【解决方案1】:

听起来您需要一种更快的方式来呈现您的观点。如果您有 800k 个样本,并且只说要在其中显示 800 个像素,那么如果您只是将其加载到 PolyLineSegment 中,那么每个像素的计算就浪费了 1000 个点。

我会重新审视“插值”这些点(这对于您的大型数据集来说确实是合并)。您要确保正确捕获每个像素中函数的动态范围:

  • 计算出图表的宽度应该是多少像素
  • 确定 X 方向上每个像素的点数
  • 对于每个点块:
    • 构建点的直方图
    • 在图表上这些点将映射到的 X 处从 max->min 画一条垂直线。这会捕获块中表示的整个范围。

如果您的点/像素接近 1,您将需要切换到简单渲染以提供更好的视觉效果。

【讨论】:

  • 谢谢,我接受这个作为答案。我之前无法压缩数据,因为我的 PCM 字节数组中有两个立体声通道。然而,在弄清楚结构之后,剩下的就很简单了:)
【解决方案2】:

要显示具有“数百万点”的波形(在您的情况下为 PCM 音频数据),您最好直接写入 WritableBitmap。这样你就只有一个渲染对象了。

您已经说过您的计算没有太多处理。尝试使用单个 UIElement 的开销太大(恕我直言)。点显示对于位图来说是微不足道的,并且有很多线绘制算法,针对速度进行了优化,可以绘制任何线段。

您可以在后台线程上绘制您的点,它们会在处理结束时更新图像的 ImageSource 以显示它。

【讨论】:

  • 我也认为它会起作用,但猜猜当你从后台线程调用 WriteableBitmap 时会发生什么?在这种情况下,将 Dispatcher.BeginInvoke 与同步一起使用会更慢。
  • 如果 WriteableBitmap 未连接到 UI 树,则您不需要在 UI 线程上更新原始像素。
  • 那么您的意思是,有没有一种方法可以将 WriteableBitmap 对象与 UI 树断开连接?此外,它是否适用于其他控件或仅适用于 WriteableBitmap?
  • 可写位图是一种图像源。它们不是可视树的一部分。没有尝试使用其他控件,但它可能会起作用,因为它们需要在 UI 线程上的唯一原因是渲染更改可见。当您添加它们时,它们将呈现其中的任何内容。
【解决方案3】:

您当然可以在后台线程上完成计算工作,并将完成的结果传递给 UI 踏板

Deployment.Current.Dispatcher.BeginInvoke

正在讨论here

【讨论】:

  • 谢谢,但这不是一个选项。大部分工作是 UI 生成,而不是计算。
猜你喜欢
  • 2018-12-08
  • 2012-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多