跨线程操作控件介绍

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];
    }, "新标题");
}
最后修改:2021 年 06 月 05 日 03 : 52 PM
如果觉得我的文章对你有用,请随意赞赏