99%的参考MSDN,所以只能算转帖了,转的MSDN的帖子,O(∩_∩)O~。
由于Windows 窗体中的控件被绑定到特定的线程,所以不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。
如何确定该控件是否需要将调用封送呢?利用的一个属性为InvokeRequired。通过该属性可以获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方可能位于创建控件所在的线程以外的线程中。尤其是当不知道什么线程拥有控件时这很有用。
InvokeRequired属性返回一个布尔值,如果控件的 Handle 是在与调用线程不同的线程上创建的(说明您必须通过 Invoke 方法对控件进行调用),则为 true;否则为 false。
Invoke 方法就是这种情况下,在拥有此控件的基础窗口句柄的线程上执行委托。下面是对该方法的重载:
Control.Invoke (Delegate) | 在拥有此控件的基础窗口句柄的线程上执行指定的委托。 由 .NET Compact Framework 支持。 |
Control.Invoke (Delegate, Object[]) | 在拥有控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托。 由 .NET Compact Framework 支持。 |
BeginInvoke 方法与Invoke 方法相似,但是它是在创建控件的基础句柄所在线程上,用指定的参数异步执行指定委托,强调其异步性。
下面有一个示例,也是MSDN上的。
//定义一个委托,调用时要用到
public delegate void MyDelegate(Label myControl, string myArg2);
private void Button_Click(object sender, EventArgs e)
{
object[] myArray = new object[2];//定义一个对象数组,也是调用时需要的
myArray[0] = new Label();
myArray[1] = "Enter a Value";
//下面一句是核心:
//使用myTextBox.BeginInvoke方法,里面有两个参数,一个是匿名委托,其中添加了一个方法
//一个是刚才定义的数组
myTextBox.BeginInvoke(new MyDelegate(DelegateMethod), myArray);
}
//这个不用说了,就是处理myTextBox的方法了
public void DelegateMethod(Label myControl, string myCaption)
{
myControl.Location = new Point(16,16);
myControl.Size = new Size(80, 25);
myControl.Text = myCaption;
this.Controls.Add(myControl);
}
这样,就实现了对myTextBox的操作
经过这样一个例子,基本上就能明白invoke的意义了