使用Invoke解决多线程间的控件访问出错

使用Invoke解决多线程间的控件访问出错

在一个WinForm界面上有一个按钮(button1)和一个文本框(textBox1),在button1的点击事件处理程序中创建一个新的线程,并期望在新线程中更改textBox1的值,容易出错的代码如下

复制代码
// 按钮点击事件处理程序
private void button1_Click(object sender, EventArgs e)
{
    
//创建新线程
    Thread processorThread = null;
    processorThread 
= new Thread(new ThreadStart(Done));
    processorThread.IsBackground 
= true;
    processorThread.SetApartmentState(ApartmentState.STA);
    processorThread.Start();
}

// 更新textBox1值
private void Done()
{
    textBox1.Text 
= "www.mzwu.com";
}
复制代码
 

运行程序点击按钮后出错,提示:线程间操作无效: 从不是创建控件“textBox1”的线程访问它。下边我们用Invoke解决这一问题:

复制代码
// 按钮点击事件处理程序
private void button1_Click(object sender, EventArgs e)
{
    
//创建新线程
    Thread processorThread = null;
    processorThread 
= new Thread(new ThreadStart(Done));
    processorThread.IsBackground 
= true;
    processorThread.SetApartmentState(ApartmentState.STA);
    processorThread.Start();
}

// 定义委托
delegate void WriteInvoke(string msg);

private void Write(string msg)
{
    textBox1.Text 
= msg;
}

// 更新textBox1值
private void Done()
{
    
this.Invoke(new WriteInvoke(Write), new object[] { "www.mzwu.com" });
}
复制代码

 

更新成功!

总结一下:在当前线程中不允许直接调用在其他线程实例化的对象,因为这种操作是线程不安全的,编译器是禁止的。但我们常常希望达到这样的目的,比如创建一个辅助线程,在辅助线程中创建WebClient对象,用来发送信息,然后把接收到的信息反馈到主线程的某个对象。这时我们就可以使用委托的方法来达到,主要步骤是把原先非法调用对象的语句单独写成更新函数,定义一个函数委托类并串接更新函数进行实例化,最后在需要更新的地方调用Invoke方法即可达到目的。

posted @   Record drip  阅读(2162)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示