2010-07-24 57 views
6

編輯:爲了澄清,我的主要目標是併發性,但不一定適合多核機).NET中的多線程繪圖?

我是相當新的對併發性的所有概念,但我想通了,我需要有並行繪圖程序,原因如下:

  • 我想要分開繪製不同部分的圖形(背景刷新頻率低於前景,保存在緩衝區中)。
  • 我希望控制優先級(比繪製複雜的圖更優先於UI響應)。
  • 我想多幀繪製每幀的計算。
  • 我想提供取消複雜的緩衝區繪製例程。

但是,作爲一名初學者,我的代碼看起來很亂,重構或bug修復變得非常尷尬,以至於我決定在做任何嚴肅的事情之前我需要更多地使用它。

所以,我想知道如何使得清潔,容易維護.NET多線程代碼,這讓我在第二天醒來時看起來很有意義。我所面臨的最大問題是構建應用程序,以便所有部分以聰明(而不是笨拙和黑客)的方式彼此交談。

歡迎任何建議,但我有空閒時間可以消化的來源(例如,不是500+頁併發論文)和C#/ VB.NET,最新版本(因爲我看到有advances)。基本上我想要一些東西,所以我可以通過玩玩具項目的概念來開始。

+0

描述你的需求在更多的細節將有助於人們回答你的問題。你想以多線程的方式繪製整個用戶界面?你是否只有一個應該是多線程的控件?您可能會以線程池結束使用繪圖層。 – 2010-07-25 00:30:16

+0

對不起,我主要關心的是如何以這種並行方式構造這樣的代碼(通常是同步的)。在這種情況下,它是關於一個控件可以在兩個或三個線程之間分割它的繪圖,但是讓我感到困難的是理解如何將併發性應用於通常在Paint事件上開始和完成的事情。 – 2010-07-25 02:56:59

回答

1

Task Parallel Library絕對是尋找簡化代碼的地方。我親自撰寫了一篇關於Parallelism with .NET 4的(半長篇)介紹,其中涵蓋了很多可能有用的概念。

但是,請注意,您可能會考慮讓繪圖單線程。您應該嘗試保持計算多線程,並在GUI線程上完成實際的繪圖操作。

大多數繪圖API都要求所有實際繪圖調用都發生在同一個同步上下文中。

這就是說,使用像ConcurrentQueue這樣的新集合類簡化了這種類型的代碼。嘗試從大量線程(生產者)的角度考慮,將「繪圖操作」添加到共享的併發隊列中 - 以及一個線程(用戶)抓取操作並執行操作。

這給你一個合理的可擴展性,但相當簡單的設計,你可以建立。

+0

呵呵我有一篇介紹文章已經在另一個標籤中打開了,我必須說它很棒(以及迄今爲止發現的最好的源代碼),我很快從中獲得了洞察力。關於繪製代碼,正如我所說的,「背景」稍微更復雜一點(它可以繪製在緩衝區中,而輕量級元素覆蓋在前一個背景緩衝區中),但是我面臨的主要問題是共享這樣的緩衝區優雅的時尚跨線程(並在正確的時間調用渲染功能,而不是把它們放在繪畫事件)。 – 2010-07-25 00:18:55

+0

我會繼續閱讀你的文章和擺弄代碼,也許這不僅僅是一本關於這個主題的大書(對我的卑微的編碼者的需求)而言是值得的。現在,+1和無限的榮譽給你! :) – 2010-07-25 00:20:45

+0

@Camilo:FYI - 迄今爲止我見過的最好的書是P&P書(我是一位評論家);)。它將於下個月發佈,但您可以閱讀預覽:http://parallelpatterns.codeplex.com/ – 2010-07-25 00:28:53

9

但我想通了,我需要有 平行繪圖函數

三個字:無法在Windows。

簡單那樣。出於兼容性的原因,標準窗口繪圖爲每個定義單線程。任何UI控件(讓我們堅持。NET世界)只能從它的創建線程中操作(因此實際上它比單線程更殘酷 - 它只是一個特定的線程)。

您可以單獨進行預先計算,但真正的繪圖已經完成了該線程。

除非你分配一個位圖,在那裏有你自己的繪圖,然後將其轉到UI線程以便繪製到窗口上。

這與整個任務並行庫等(我downvoted)沒有任何關係,但可以追溯到一個非常古老的要求,爲了簡單的原因和兼容性保持在周圍。這就是任何UI線程都會成爲市場的主要原因。

另請注意,多線程繪圖如果自己實施,會產生嚴重的影響。哪一個贏得光學(留在前臺)?使用多線程時,這不是真正可確定的。不過,您可以自由嘗試。

在這種情況下:

  • 擁有自己的緩衝區和同步是必須的。遠離任何窗口級圖形庫(WPF或Winforms),除了最後一步(原始位圖)。

  • DirectX 11據稱有一些支持多線程調用,但我不確定多遠。

+0

實際上,我在另一個繪製例程的另一個線程繪製了緩衝區,並且使用DrawImageUnscaled()在UI線程上繪製該緩衝區,並且我甚至使用GDI +(在繪製線程上),因爲它的性能是好的 - 我擔心的是percieved性能比實際性能要高(例如,具有100%響應的UI所有的時候,甚至在繪製「背景」時,因爲這個緩衝區覆蓋了一層,可以讓用戶認爲應用程序比實際更具響應性,就像光標所做的一樣,從不凍結)。 – 2010-07-25 01:24:21

+0

是的,這是有效的 - 因爲對於Windows來說繪圖不是來自另一個線程;) – TomTom 2010-07-25 01:43:55