.
之前提到的執行緒是使用backgroundworker,詳細可以參考前面的文章
這篇主要為執行緒的另外一種方法,如果在執行緒中刷UI會依樣遇到執行緒衝突的問題,跟backgroundworker刷UI的方式不太相同,這邊是使用 invoke來調用Callback函數來刷新,原理為將執行緒導回UI執行緒,因為機制關係不允許在其他執行緒中操作UI
以下為範例程式
此程式主要是使用一個無限迴圈來不斷的累加數字,直到使用者按暫停為止
using System;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
usingSystem.Windows.Forms;
usingSystem.Threading;
namespacethread_test2
{
public partial class Form1 : Form
{
Thread _th; //宣告執行緒
public Form1()
{
InitializeComponent();
}
//委派 UpdateUICallBack 來更新UI
private delegate voidUpdateUICallBack_Text(int value, Control ctl);
private delegate void UpdateUICallBack_Label(stringvalue, Control ctl);
private voidbutton1_Click(object sender, EventArgs e)
{
Update_Label("start",label1); //更新Label
_th = newThread(ExecuteInForeground);
//宣告新執行緒做指定動作
_th.Start(); //開啟執行緒
//Thread.Sleep(1000);
}
private void ExecuteInForeground()
{
int i=0;
while (true)
{
i++;
Update_Text(i,textBox1); //更新textBox
}
}
private void Update_Text(intvalue, Control ctl)
{
try{
//判斷這個TextBox的物件是否在同一個執行緒上
//當InvokeRequired為true時,表示在不同的執行緒上,所以進
//行委派
if (this.InvokeRequired)
{
UpdateUICallBack_Textuu = new
UpdateUICallBack_Text(Update_Text);
this.Invoke(uu,value, ctl);
}
Else
//表示在同一個執行緒上了,所以可以正常的呼叫到這個TextBox物件
{
ctl.Text =value.ToString();
}
}
catch
{
MessageBox.Show("執行緒被關閉");
}
}
private void Update_Label(stringvalue, Control ctl)
{
if (this.InvokeRequired)
{
UpdateUICallBack_Labeluu = new
UpdateUICallBack_Label(Update_Label);
this.Invoke(uu,value, ctl);
}
else
{
ctl.Text =value.ToString();
}
}
private voidbutton2_Click(object sender, EventArgs e)
{
Update_Label("stop",label1);
_th.Abort(); //停止執行緒
}
}
}
開啟
暫停