关于C# this.InvokeRequired的问题
请问各位兄弟,我这样子写的一段程序,是用来线程去调用窗体控件,进行复制,可是我这样写,程序会卡死的~~~这是为什么了??还有就是this.Invoke与this.BeginInvoke的怎样区别的?如果用了怎样this.BeginInvoke之后,需要调用this.EndInvoke吗?
C# code
public delegate void DeleTtt();
public delegate void DeleTttt();
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread t1 = new Thread(new ThreadStart(progressBarSample));
t1.IsBackground = true;
t1.Start();
Thread t2 = new Thread(new ThreadStart(lblText));
t2.IsBackground = true;
t2.Start();
}
private void progressBarSample()
{
if (this.InvokeRequired)
{
this.Invoke(new DeleTttt(lblText));
}
else
{
for (int i = 0; i < this.progressBarSample2.Properties.Maximum; i += 50)
{
this.progressBarSample2.Position += i;
Thread.Sleep(1500);
}
}
}
private void lblText()
{
if (this.InvokeRequired)
{
this.Invoke(new DeleTtt(lblText));
}
else
{
while (true)
{
label2.Text += ".";
if (label2.Text.Length >= 4)
{
label2.Text = String.Empty;
}
Thread.Sleep(1000);
}
}
}
}
------解决方案--------------------Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上
执行指定的委托。
Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句柄所在线程上
异步执行指定委托。
以下为实际应用中碰到的问题,在主线程中启动一个线程,然后在这个线程中启动serviceForm,然而在线程启动后,往serviceForm发送指令,serviceForm.IsHandleCreated老是报serviceForm = null,无法执行指令,采用延时的办法可以解决此问题,但不是高效的办法,后来在serviceForm.Load += new EventHandler(serviceForm_Load);serviceForm_Load事件中添加指令,发送成功。主要原因还是多线程所致。
------解决方案--------------------
(一)Control的Invoke和BeginInvoke
我们要基于以下认识:
(1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不同的。
(2)Control的Invoke和BeginInvoke的参数为delegate,委托的方法是在Control的线程上执行的,也就是我们平时所说的UI线程。
我们以代码(一)来看(Control的Invoke)
private delegate void InvokeDelegate();
private void InvokeMethod(){
//C代码段
}
private void butInvoke_Click(object sender, EventArgs e) {
//A代码段.......
this.Invoke(new InvokeDelegate(InvokeMethod));
//B代码段......
}
你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上
A------>C---------------->B
解释:(1)A在UI线程上执行完后,开始Invoke,Invoke是同步
(2)代码段B并不执行,而是立即在UI线程上执行InvokeMethod方法,即代码段C。
(3)InvokeMethod方法执行完后,代码段C才在UI线程上继续执行。
看看代码(二),Control的BeginInvoke
private delegate void BeginInvokeDelegate();
private void BeginInvokeMethod(){
//C代码段
}
private void butBeginInvoke_Click(object sender, EventArgs e) {
//A代码段.......
this.BeginInvoke(new BeginInvokeDelegate(BeginInvokeMethod));
//B代码段......
}
你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上
A----------->B--------------->C慎重,这个只做参考。。。。。,我也不肯定执行顺序,如果有哪位达人知道的话请告知。
解释::(1)A在UI线程上执行完后,开始BeginInvoke,BeginInvoke是异步
(2)InvokeMethod方法,即代码段C不会执行,而是立即在UI线程上执行代码段B。
(3)代码段B执行完后(就是说butBeginInvoke_Click方法执行完后),InvokeMethod方法,即代码段C