.
在執行緒如果直接指定元件更新其內容時,都會跳出 "跨執行緒作業無效"
遇到此問題時的解訪有兩種
第一種是設定元件屬性
Form.CheckForIllegalCrossThreadCalls = False;
這樣就不會跳出上述問題,只是非常不建議使用此方式
程式執行時可能會出現很多無法預期的錯誤
=======================================================
第二種為正規的方式,使用委派來跨執行緒存取UI
實際的做法如下,隨意舉個簡單的例子
private delegate void UpdateUI( String str, Control ctl); //宣告委派
private void updateText( String str, Control ctl)
{
if( this.InvokeReruired)
{
UpdateUI uu = new UpdateUI( updateText);
this.Invoke( uu, str, ctl);
}
else
{
ctl.text = str;
}
}
=======================================================
第三種方式就是使用 backgroundworker更新UI,範例如下
BackgroundWorker 元件請從工具箱中拖曳到UI上
可以點選屬性設定事件
private BackgroundWorker worker;
//初始化
private void init()
{
worker= new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += new DoWorkEventHandler(do_work);
worker.ProgressChanged += new
ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
}
//背景執行
private void do_work(object sender, DoWorkEventArgs e)
{
for(int i = 0 ; i < 60000 ; i++) //每秒讀取Sensor數值,持續60000次
{
read_Sensor_Data();
Thread.sleep(1000);
worker.ReportProgress(i);
}
}
//如果中途按下取消鍵
private void end_Click(object sender, EventArgs e)
{
if (worker.WorkerSupportsCancellation == true)
{
worker.CancelAsync();
}
}
//處理進度條更新
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage / 60000 * 100;
this.progress.Text = e.ProgressPercentage.ToString() + "%";
}
//讀取完畢
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.progress.Text = "read complete";
}