2010-10-18 70 views
5

嘿,我的代碼序列是這樣的:GUI直到代碼完成

label.Text = "update 0"; 
doWork(); 
label.Text = "update 1"; 
doWork2(); 
label.Text = "update 2"; 

基本上,GUI不更新可言,直到所有的代碼執行完畢。如何克服這一點?

回答

16

一個醜陋的黑客是使用Application.DoEvents。雖然這有效,但我建議不要這樣做。

更好的解決方案是使用BackgroundWorker或單獨的線程執行長時間運行的任務。不要使用GUI線程,因爲這會導致它阻塞。

需要注意的一個重要的事情是,必須在GUI線程上對GUI進行更改,因此您需要將控制權轉移回GUI線程以便標記更新。這是通過使用Invoke完成的。如果您使用BackgroundWorker,則可以使用ReportProgress - 它將自動爲您處理調用Invoke。

+3

有關[背景工作者類](http:// bit。ly/a9VgVn)和一個[如何使用它的例子](http://bit.ly/ailRTF) – codingbadger 2010-10-18 12:42:08

0

當前,您的所有處理都是在主(UI)線程上執行的,因此必須先完成所有處理,然後UI線程纔有空閒週期來重新繪製UI。

你有2種方法克服這一點。不推薦的第一種方法是使用
Application.DoEvents();只要希望處理Windows消息隊列,就可以運行它。

其他建議的方法:創建另一個線程來執行處理,並使用委託將UI更新傳遞迴UI線程。如果您是多線程開發的新手,那麼可以嘗試使用BackgroundWorker。

2

當UI獲取WM_PAINT消息來重新繪製屏幕時,UI將更新。如果您正在執行您的代碼,則不會執行消息處理例程。

所以你可以做以下操作以啓用執行消息處理程序的:

Application.DoEvents,調用消息處理程序,然後返回。這對於大型工作來說並不理想,但對於小型程序而言,它可能是一種更簡單的解決方案,而不是引入線程。

0

GUI以這種方式運行代碼時無法更新。 Windows上的GUI依賴於消息處理,並且當你處於代碼中時消息處理被暫停 - 無論你如何處理標籤,按鈕等,它們都將在代碼退出後更新,並且表單的主要消息循環是處理。

您有幾種選擇在這裏:

  • 移動處理其他線程和麪臨的invoke()situtations
  • 調用的DoEvents(),並允許GUI你的DoWork之間刷新調用
  • 做的所有工作並稍後更新