2011-08-19 88 views
1

我正在使用PolyLineSegment和點在Silverlight中構建折線圖控件。它的工作方式與預期的一樣,但是當需要可視化的數據太多時(太多點),應用程序會長時間凍結。我無法將代碼移動到單獨的線程上,原因很明顯 - 它直接處理UI元素,所以當我嘗試從單獨的線程調用它們時,它會導致異常(即使UI元素尚未呈現)。Silverlight - 是否可以在後臺線程上創建UI元素?

是否有任何方法在後臺線程上動態創建UI元素,然後將它們傳遞給UI線程進行渲染?如果不是,那麼可能的解決方案是什麼?我正在考慮創建一個位圖圖像而不是實際的控件,但在這種情況下不會有太多的交互性。

+0

什麼是最花時間?它是元素的實際渲染還是在創建每個元素之前執行一系列計算?如果是後者,你可能可以在後臺線程上運行這些計算,然後通過「Dispatcher」對每個元素的創建進行編組。 – dlev

+0

我的代碼中沒有太多的計算,而是大量的數據。我在談論數百萬分。縮小它們並不是最好的選擇。 – Dmitry

+0

這使得它更加困難。但是,如果您擁有數百萬的點數,它們如何一次顯示在屏幕上?即使在1024x768的時候,也有800K像素。您是否在滾動查看器中進行屏幕外渲染?如果是這樣,你可以虛擬化用戶界面嗎?如果沒有,你可能會以某種方式合併點數;這可以做到的數據? – dlev

回答

2

這聽起來像你需要以更快的方式呈現你的觀點。如果您只有800k個樣本,並且只有800個像素才能顯示它們,那麼如果您只將它加載到PolyLineSegment中,那麼每像素計算會浪費1000個點。

我會重新訪問'插入'點(這對您的大型數據集來說非常合適)。你要確保你捕捉功能的動態範圍中的每個像素正確:

  • 圖有多少個像素寬的圖形應該是
  • 確定多少分每個像素在X方向
  • 對於點的每個組塊:
    • 生成點
    • 的直方圖在X,其中這些點將映射到上繪製的曲線圖從MAX-> min的垂直線。這捕獲了塊中表示的全部範圍。

如果您的點/像素達到接近1你要切換到簡單的渲染,以提供更好的視覺效果爲好。

+0

謝謝,我接受這個答案。我之前無法壓縮數據,因爲我的PCM字節數組中有兩個立體聲通道。然後,找出結構後,其餘的是非常簡單的:) – Dmitry

+0

好聽,好運! –

0

你當然可以做後臺線程(S)的計算工作,並與

Deployment.Current.Dispatcher.BeginInvoke

這是討論通過最終的結果到UI胎面here

+0

謝謝,但它不是一個選項。大部分工作是用戶界面生成,而不是計算。 – Dmitry

2

對於顯示波形(在你的情況下,PCM音頻數據)與「百萬點」,你最好直接寫入一個WritableBitmap。然後你只有一個渲染對象。

你已經說過你的計算沒有太多的處理。嘗試使用單個UIElements的開銷太大(恕我直言)。點顯示對於位圖來說是微不足道的,並且有很多線繪圖算法,針對速度進行了優化,以執行任何線段。

您可以將您的點繪製在後臺線程上,並在處理結束時更新圖像的ImageSource以顯示它。

+0

我也認爲這將是工作,但猜測當你從後臺線程調用WriteableBitmap會發生什麼?在這種情況下,使用Dispatcher.BeginInvoke進行同步的速度更慢。 – Dmitry

+0

如果WriteableBitmap未連接到UI樹,則不需要在UI線程上更新原始像素。 –

+0

所以你在說什麼,是有辦法從UI樹中斷開WriteableBitmap對象?此外,它可以與其他控件或只是WriteableBitmap? – Dmitry

相關問題