視窗程式開發時, 為避免執行時間較長的函數將視窗凍結而使用執行緒 (Threading) 執行函數, 但執行緒和視窗元件互動卻發生跨執行緒間的存取權限問題 (※建立視窗元件的執行緒與使用的執行緒不同).
前言
為了避免跨執行緒間的視窗元件操作問題, 使用委派 (Delegate) 來處理這類問題.
本文
委派的寫法像替元件寫個 Callback, 判斷是不是在同一個執行緒內, 如果 不是 則呼叫 Callback Function (底下 if 區塊內), 如果 是 則將需求完成.
Sample Code
- 更新 comboBox 的狀態:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| private delegate void ComboBox_update(bool status);
private void combobox_update(bool status) { if (this.InvokeRequired) { ComboBox_update myUpdate = new ComboBox_update(combobox_update); this.Invoke(myUpdate, status); } else { comboBox_project.Enabled = status; } } private void button1_Click(object sender, EventArgs e) { combobox_update(true); }
|
或者
2. 更新 textBox 的狀態:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public void update_msg_windows(string msg) { string t = DateTime.Now.ToString("MM/dd HH:mm:ss.fff ");
if (txtBox_msg_window.InvokeRequired) { Action<string> actionDelegate = (x) => { this.txtBox_msg_window.AppendText(x.ToString()); }; this.txtBox_msg_window.Invoke(actionDelegate, t + msg + "\r\n"); } else { txtBox_msg_window.AppendText(t + msg + "\r\n"); txtBox_msg_window.Refresh(); } break;
}
private void button1_Click(object sender, EventArgs e) { update_msg_windows("Hello World!"); }
|
- 更新 RichBox 的狀態:
甚至透過重載實現 輸出預設顏色 或者 改變顏色的訊息,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public void AppendRichBoxLog(string msg) { try { if (InvokeRequired) { this.Invoke(new Action<string>(AppendRichBoxLog), new object[] { msg }); return; } DateTime dt = DateTime.Now; richTextBox_log.AppendText(dt.ToString("yyyy/MM/dd HH:mm:ss") + " " + msg + "\r\n"); richTextBox_log.ScrollToCaret(); } catch(Exception ex) { MessageBox.Show(ex.Message); } }
public void AppendRichBoxLog(string msg, Color textColor) { try { if (InvokeRequired) { this.Invoke(new Action<string, Color>(AppendRichBoxLog), new object[] { msg, textColor }); return; } DateTime dt = DateTime.Now; Color _r = richTextBox_log.SelectionColor; richTextBox_log.SelectionColor = textColor; richTextBox_log.AppendText(dt.ToString("yyyy/MM/dd HH:mm:ss") + " " + msg + "\r\n"); richTextBox_log.SelectionColor = _r; richTextBox_log.ScrollToCaret(); } catch(Exception ex) { MessageBox.Show(ex.Message); } }
|