2010-03-11 38 views
0

在Windows窗體的UI線程中是否存在(或者,你有自己的)首選方法在片段中執行後臺處理?像MFC中的OnIdle()?在UI線程上的後臺處理? (Winforms)

在本機Windows編程中,您可以滾動您自己的消息循環來執行此操作,但Application.Run()不允許我們訪問消息循環。

Application.Idle事件讓我們無法重複觸發它。

我想你可以用P/Invoke(因爲沒有託管版本)調用本機PostMessage()來發布自己的私有「WM_IDLE」消息,並覆蓋WndProc()來捕獲它。我不知道這將如何與Application.Run()相處。

到目前爲止,我已經爲此使用了一個短暫定時器,但恐怕我可能會失去睡眠週期,尤其是因爲實際的定時器分辨率比標稱的1毫秒最少更粗。

回答

1

我見過的最好的選擇是使用Managed DirectX Render Loop designed by Tom Miller的修改版本。通過在渲染循環中添加對Thread.Sleep()的調用,可以顯着降低CPU使用率。

這確實需要一個P/Invoke調用來跟蹤應用程序仍處於空閒狀態,但只要空閒,您就可以製作一個「定時器」,在空閒階段持續觸發,並用它來處理。

這就是說,在現代系統中,你幾乎總是有額外的核心。我會建議只在真正的後臺線程上進行處理。

+0

1. AFAIK我的很多用戶沒有這個定義的「現代系統」。 2. UI正在快速使用由後臺進程生成的新數據,因此所有常見的多線程問題。 3. 99%的工作是在後臺進程中,因此用於UI和背景的獨立內核不會購買更多的總吞吐量。 – 2010-03-11 01:23:38

+0

@Conrad:爲什麼我實際上給了你一個完全停留在UI線程上的選項......但是,即使是最近3-5年來的「低端」系統,通常也有2個內核。將所有處理置於後臺線程中,即使在單核低端系統中,您也可以保持UI活躍,並且可能比在空閒時間嘗試執行預定處理更容易。這就是說,上面的方法工作得很好... – 2010-03-11 16:24:39

+0

@康拉德:我只是意識到 - 我有錯誤的鏈接!我放在上面的那個應該更有意義......它將Application.Idle與AppStileIdle結合在一個循環中 - 允許你做你想做的事。 (對不起 - 我先前貼錯了)。 – 2010-03-11 16:27:12

0

我想到了我自己可能的答案,靈感來自於裏德關於多線程的討論。我可能有一種方法來重新觸發Application.Idle:

創建一個隱藏窗體,我們稱之爲formRetrigger。

在Application.Idle中,在線程池線程上啓動我的Retrigger()方法。 ()調用formRetrigger.InvokeOnClick()(或任何其他「Control.Invoke」方法)。我希望這會通過應用程序的隊列啓動另一條消息,導致Idle再次觸發。

相關問題