豐富的用戶體驗是所有交互式應用程序的主要方面。需要用戶交互的軟件必須儘可能快地響應用戶的活動。與此同時,應用程序必須能夠處理數據以便將結果顯示給用戶。
在應用程序中使用多個線程可以將用戶界面 (UI) 執行的任務與後臺執行的任務分開。通過此方式組織任務,可以由 UI 響應用戶輸入,同時由後臺進程進行數據處理。
創建輔助線程
應用程序可以創建一個或多個線程以執行方法。創建輔助(或從屬)線程的第一個步驟是創建 ThreadStart 代理,指定要由該線程執行的方法。然後將 ThreadStart 代理傳遞給 Thread 類的構造函數。例如,要啓動新的線程並執行MyFunction 方法,請調用 Thread 類的 Start 方法,如下所示:
ThreadStart starter = new ThreadStart(MyFunction); Thread t = new Thread(starter); t.Start();
從輔助線程更新用戶界面
您可以使用 Control.Invoke 從 UI 線程以外的其他線程更新用戶界面 (UI)。此方法在 UI 線程上的控件線程上下文中執行代理。.NET Framework 精簡版只支持 .NET Framework 完整版中的重載Control.Invoke 方法。Control.Invoke 只使用一個參數:一個指定在 UI 線程上執行哪個方法的代理。該代理的類型必須爲EventHandler,並且具有以下簽名:
void MyFunctionName(object sender, EventArgs e)
需要注意的一點是,如果要在輔助線程中更新 UI,就必須在代碼中調用 Application.DoEvents()。調用 Application.DoEvents() 可確保輔助線程激發的任何事件都由該 UI 線程處理。
下面的示例代碼說明如何創建輔助線程,然後從 UI 線程和輔助線程更新名爲 listBox1 的 ListBox 控件:
1// 此變量將保留輔助線程設置的一些文本
2public string Message = "";
3
4// 創建輔助線程,然後將項目從 UI 線程添加到
5// ListBox 中
6public void DoThreading()
7 {
8 // 創建並啓動輔助線程
9 ThreadStart starter = new ThreadStart(this.UpdateListBox);
10 Thread t = new Thread(starter);
11 t.Start();
12
13 // 循環 4 次,每次都向 ListBox 中添加一條消息
14 for(int i = 0; i < 4; i++);
15 {
16 this.listBox1.Items.Add("來自 UI 線程的消息");
17 this.listBox1.Update();
18 // 處理 UI 線程中排隊的事件
19 Application.DoEvents();
20 // 將進程掛起一秒鐘
21 Thread.Sleep(1000);
22 }
23 this.listBox1.Items.Add("來自 UI 線程的上一條消息");
24 this.listBox1.Update();
25}
26
27public void UpdateListBox()
28 {
29 for(int j = 0; j < 5; j++)
{
31 // 設置要從輔助線程添加到 ListBox 中的
32 // 消息
33 this.Message = "輔助線程的循環數 = " + j.ToString();
34 // 在 ListBox 的線程上下文中調用 WorkerUpdate
35 // 方法
36 this.listBox1.Invoke(new EventHandler(WorkerUpdate));
37 Thread.Sleep(700);
38 }
39}
40// 爲更新 ListBox 從輔助線程中
41// 調用的代理
42public void WorkerUpdate(object sender, EventArgs e)
43 {
44 this.listBox1.Items.Add(this.Message);
45 this.listBox1.Update();
46}