winform 开发之Control.InvokeRequired
Control.InvokeRequired 获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。
InvokeRequired 当前线程不是创建控件的线程时为true。
比如你可以自己开一个Thread,或使用Timer的事件来访问窗体上的控件的时候,在线程中窗体的这个属性就是True的。
简单的说,如果有两个线程,Thread A和Thread B,并且有一个Control c,是在Thread A里面new的。
那么在Thread A里面运行的任何方法调用c.InvokeRequired都会返回false。
相反,如果在Thread B里面运行的任何方法调用c.InvokeRequired都会返回true。
是否是UI线程与结果无关。(通常Control所在的线程是UI线程,但是可以有例外)
也可以认为,在new Control()的时候,control用一个变量记录下了当前线程,在调用InvokeRequired时,返回当前线程是否不等于new的时候记录下来的那个线程。
--------------------
我理解:如果InvokeRequired==true表示其它线程需要访问控件,那么调用invoke来转给控件owner处理。
实例如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; namespace WinThreadNew { public partial class WinThreadNew : Form { int pro = 0; Thread backWork = null; //后台线程 public WinThreadNew() { InitializeComponent(); } private void btnStart_Click(object sender, EventArgs e) { backWork = new Thread(new ThreadStart(doWork)); //创建新的线程 backWork.Start(); //启动线程 } public delegate void DelegateUpdateUIPro(); private void doWork() { for (int i = 0; i < 100; i++ ) { pro++; UpdateUIPro(); //在新线程中更新ui Thread.Sleep(100); } } private void UpdateUIPro() { //更新ui时需要判断InvokeRequired 属性 if (this.InvokeRequired) { this.BeginInvoke(new DelegateUpdateUIPro(UpdateUIPro)); } else { this.lblPro.Text = pro.ToString() + "%"; } } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { this.backWork.Abort(); this.backWork.Join(); } } }