2012-07-25 90 views
10

我需要一些正確的編碼建議:好編碼? (多消息循環)

我正在使用多個串行連接的程序。每條通信線路都有一個控制器作爲抽象層。在控制器和串行端口之間插入一個協議,將數據封裝在包中,準備傳輸。該協議負責處理失敗的傳送,重新發送等。 爲確保GUI不會掛起,每條連接線(協議和串行端口)都在單獨的線程上創建。控制器由主線程處理,因爲它在GUI中具有控件。當我創建線程時,我選擇在它們上創建一個消息循環(Application.Run()),因此,如果沒有工作輪詢緩衝區併產生結果,我只需調用線程(BeginInvoke)並使用消息循環作爲緩衝區。目前這個工作很好,至今沒有嚴重的問題。

我現在的問題是:這是「好的編碼」,或者我應該使用一個while循環的輪胎,而不是輪詢緩衝區?或第三件事?

我想展示代碼,但到目前爲止它已經有數千行代碼,所以如果您需要查看代碼的任何部分,請詳細說明。 :)

謝謝。

回答

4

在每個線程中使用消息循環非常好, Windows針對此場景進行了優化。您有權避免輪詢,但您可能希望查看其他更高效的基於事件的設計,例如準備傳輸包並呼籲SetEvent通知它已準備就緒的線程或信號量和線程安全隊列馬丁詹姆斯建議。

+0

不是,不。 WM_COPYDATA適用於進程之間的通信。使用它在一個進程內的線程間通信毫無意義。只需通過指針傳遞緩衝區/ blob /任何對象就簡單多了,例如。通過將* Buffer轉換爲消息。lParam,PostMessage()並在「另一端」回退。 – 2012-07-25 08:27:25

+0

Windows消息隊列已針對通信TO GUI線程進行了優化。從GUI線程到非GUI工作線程的通信不是最佳的。即使是一個簡單的基於信號量的,非優化的生產者 - 消費者隊列,其速度比WMQ快四倍。在大多數應用中,P-C隊列性能通常不是問題。 – 2012-07-25 08:32:23

+0

我同意這兩點。我將編輯出WM_COPYDATA;我沒有清楚地思考。關於消息隊列,這是一個廣義的基於事件的解決方案。根據他的應用程序的要求,其他模型可能會更好。 – tenfour 2012-07-25 08:38:25

1

我不是100%肯定,你在做什麼,但在這裏,以「填補」了一下它聽起來並不壞:)

當你的應用程序處於空閒狀態,(無通訊),是CPU使用0%?

您的應用沒有睡眠(0)/睡眠(1)或類似的輪詢循環嗎?

它的延遲合理嗎?

如果答案是三個「YES」,你應該罰款:)

有幾個,(很少!),情況輪詢結果等是一個好主意,(例如,當。線程中的事件發生頻率非常高,以致於向GUI發送每個進度事件都會使其不堪重負),但大多數情況下,這只是糟糕的設計。

+0

這個程序的目的是控制1-4個(迄今爲止)框,每個包含一個Arduino。每個Arduino都連接到模擬器系統的數字I/O。並行模擬器系統需要一個盒子。模擬器。模擬器是我工作的公司的研發部分。 Windows程序具有在運行時重新編程Arduino引腳的易用性,以及讀/寫引腳的高/低狀態。 – Anders 2012-07-25 09:32:10

+0

Triple YES從這裏..我試圖改變代碼爲緩衝區輪詢,與thread.yields如果沒有數據,並使程序缺乏一點,所以我想我很好,消息循環:) – Anders 2012-07-25 09:37:28

+0

嗯,我可能已經使用了稍微不同的隊列等,但如果你的應用程序足夠高效,響應迅速,不會崩潰,誰在乎:)) – 2012-07-26 08:38:15