【Winform】非UI线程访问UI控件
委托异步中,Invoke的参数是函数实参和回调。dlg.Invoke(para, funcCallback)
非UI线程访问控件:
1.Invoke
control.Invoke(delegate dd, new object[] { str }) //第二个参数是传入委托的实参
control.BeginInvoke(delegate dd)
//当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它
delegate void AddDg(string str); //声明一个委托
private void AddStr(string str)
{
if (textBox1.InvokeRequired)
{
AddDg dg = new AddDg(AddStr);
textBox1.Invoke(dg, str); //在创建textBox1的线程上同步执行AddStr()。阻塞直到AddStr()执行完。
textBox1.BeginInvoke(dg, str); //另起一个线程执行AddStr()
}
else
{
textBox1.Text += str; //若是创建textBox1的线程想访问的话直接赋值
}
}
2.BackgroundWorker组件
private void button4_Click(object sender, EventArgs e)
{
using (BackgroundWorker bw = new BackgroundWorker())
{
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync("Tank");
}
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
// 这里是后台线程, 是在另一个线程上完成的
// 这里是真正做事的工作线程
// 可以在这里做一些费时的,复杂的操作
Thread.Sleep(5000);
e.Result = e.Argument + "工作线程完成";
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//这时后台线程已经完成,并返回了主线程,所以可以直接使用UI控件了
this.label4.Text = e.Result.ToString();
}