跨线程操作控件介绍
C#中是禁止跨线程操作控件的,可以利用 Control 的 InvokeRequired 属性和 Invoke 方法来处理,以确保线程安全。
通过 InvokeRequired 属性判断调用方在对控件进行方法调用时是否必须调用 Invoke 方法。
常规示例:
private System.Windows.Forms.TextBox tbxTitle;//文本框
//委托
private delegate void InvokeCallback(string title);
//操作事件方法
private void editTitleEvent(string title)
{
if (tbxTitle.InvokeRequired) //其它线程访问
{
InvokeCallback callback = new InvokeCallback(editTitleEvent);
tbxTitle.Invoke(callback, new object[] { title });
}
else //当前线程访问
{
tbxTitle.Text = title;
}
}
//一个按钮点击事件
private void btnEditTitle_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(editTitle));
thread.Start();
}
private void editTitle() {
//子线程中操作访问
editTitleEvent("新标题");
}泛型委托封装
封装如下:
private delegate void ControlInvokeCallback<T>(T control, ControlOperateCallback<T> controlOperateCallback, params object[] param) where T : Control;
private delegate void ControlOperateCallback<T>(T control, params object[] param);
private void ControlOperateEvent<T>(T control, ControlOperateCallback<T> controlOperateCallback, params object[] param) where T : Control
{
if (control.InvokeRequired)
{
ControlInvokeCallback<T> callback = new ControlInvokeCallback<T>(ControlOperateEvent);
control.Invoke(callback, control, controlOperateCallback, param);
}
else
{
controlOperateCallback(control, param);
}
}调用如下:
//参照前面的示例代码,省略其余代码,只保留关键调用部分
private void editTitle() {
//子线程中操作访问
ControlOperateEvent(tbxTitle, (control, param) => {
control.Text = (string)param[0];
}, "新标题");
}