如果在新的线程中直接使用其它线程创建的windows窗体控件时,会报错误“线程间操作无效,不是从创建控件' '的线程访问它。”因为windows不允许从创建控件以外的线程调用控件。有两种方法可以实现非GUI线程调用控件。一种为基于TAP的异步编程方法,一种为使用Invoke、BeginInvoke的方法。
1. TAP异步方法
这种方法比较简单,也比较现代化,推荐使用这种方法,将click委托方法标记为async异步方法,使用Task取线程,直接可在Task委托内调用控件。待到异步线程执行到控件的调用时,状态机会交给GUI线程去处理。
private async void button1_Click(object sender, EventArgs e) { await Task.Run(() => { //异步线程中执行计算 //... this.textBox1.Text = "ggx"; }); }
2. 使用Invoke(BeginInvoke)
控件的基类Control下提供的Invoke或BeginInvoke方法。将要对目标控件执行的操作写到委托中,然后将委托作为参数传递给BeginInvoke方法。创建一个窗体控件,在窗体控件中添加一个button按钮控件和一个textBox控件。点击按钮改变textBox的text值,为了说明问题,我们在新的线程中做改变textBox属性的工作。具体的代码和说明如下。
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //创建一个action委托,将改变textBox值的过程写到委托中 Action act = () => { this.textBox1.Text = "ggx"; }; //创建一个新的线程 Task task = new Task(() => { //异步线程中执行计算 //... //调用BeginInvoke方法,将委托传入 this.BeginInvoke(act); }); //启动线程 task.Start(); } }
参考:
https://www.cnblogs.com/darksoulson/p/3428577.html