下面通過窗體示例演示以下操作-點擊按鈕後:①將標簽內容改成:“Doing”,並將按鈕禁用(表示執行中);②線程掛起3秒(模擬耗時操作);③啟用按鈕,將標簽內容改為:“Complete”(表示執行完成);
1 public partial class Form1 : Form 2 { 3 public Form1() 4 { 5 InitializeComponent(); 6 } 7 8 private void btnDo_Click(object sender, EventArgs e) 9 { 10 btnDo.Enabled = false; 11 lblText.Text = @"Doing"; 12 13 Thread.Sleep(3000); 14 15 btnDo.Enabled = true; 16 lblText.Text = @"Complete"; 17 } 18 }
可是執行結果卻是:
圖1-1
發現的問題:好像沒有變成“Doing”,並且拖動窗口的時候卡住不動了,3秒後突然變到想拖動到的位置,並且文本變成“Complete”?
【分析】GUI 程序在設計中要求所有的顯示變化都必須在主 GUI 線程中完成,如點擊事件和移動窗體。Windows 程序時通過 消息來實現,消息放入消息泵管理的消息隊列中。點擊按鈕時,按鈕的Click消息放入消息隊列。消息泵從隊列中移除該消息,並開始處理點擊事件的代碼,即 btnDo_Click 事件的代碼。btnDo_Click 事件會將觸發行為的消息放入隊列,但在 btnDo_Click 時間處理程序退出前(線程掛起 3 秒退出前),消息都無法執行。接著所有行為都發生了,但速度太快肉眼分辨不了。
圖1-2 點擊事件
圖1-3 點擊事件具體執行過程
【分析】如果 btnDo_Click 事件處理程序能先將前兩條消息壓入隊列,然後將自己從處理器移出,在4秒後再將自己壓入隊列。這樣可以保持響應,並保證所有的消息可以在線程掛起的時間內被處理。
【原文地址】http://www.cnblogs.com/liqingwen/p/5877042.html