2017-03-07 29 views
0

我有以下代碼:標籤在WPF應用程序不更新

label1.content = "Start"; 
bool a = executeLongTask(); 
label1.content = "Done"; 

出於某種原因,標籤只能被更新爲「完成」完成executeLongTask()方法之後。它完全跳過顯示「開始」消息。

爲什麼當應用程序運行時標籤沒有被設置爲「開始」,以及如何在不使用多線程的情況下將其更新爲「開始」?

executeLongTask()方法通過調用PowerShell腳本並等待輸出,然後繼續執行label1.content =「Done」;

回答

3

由於某些原因,標籤只有在executeLongTask()方法完成後纔會更新爲「完成」。它完全跳過顯示「開始」消息。

這是因爲UI線程需要返回到其主循環以便處理WM_PAINT更新。當您第一次設置標籤時,WPF會記下它在標籤返回到消息處理循環時應該重繪標籤。然後,用戶界面在executeLongTask方法中保持忙碌狀態,然後再次設置標籤,並且WPF再次記下它應該重新繪製標籤。當你將控制返回到UI消息循環時,它終於有機會實現重繪並更新你在屏幕上看到的內容。

我該如何將它更新爲「開始」,而不使用多個線程?

最簡單的解決方案使用多個線程。例如:

label1.content = "Start"; 
bool a = await Task.Run(() => executeLongTask()); 
label1.content = "Done"; 

或者,你可以重寫executeLongTask異步行動,那麼你就不會需要一個單獨的線程:

label1.content = "Start"; 
bool a = await executeLongTaskAsync(); 
label1.content = "Done"; 
+0

非常感謝你爲你詳細和翔實的帖子。我沒有意識到WPF記錄了要更新的標籤,然後在從方法返回時實際設置它。因此我很困惑,爲什麼它不能只設置第一個標籤,執行長時間執行,然後設置最後一個標籤。再次感謝你,我想我會用你提供的第一個解決方案。 – John

1

文本只會在函數返回後更新。如果您希望它在executeLongTask()正在運行時更新,則需要使用async/await模式。將允許您返回控制權,直到完成長任務。

相關問題