浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别.doc_第1页
浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别.doc_第2页
浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别.doc_第3页
浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别.doc_第4页
浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别.doc_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别今天无意中看到有关Invoke和BeginInvoke的一些资料,不太清楚它们之间的区别。所以花了点时间研究了下。据msdn中介绍,它们最大的区别就是BeginInvoke属于异步执行的。 Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上执行指定的委托。 Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句柄所在线程上异步执行指定委托。 msdn说明: 控件上的大多数方法只能从创建控件的线程调用。 如果已经创建控件的句柄,则除了 InvokeRequired 属性以外,控件上还有四个可以从任何线程上安全调用的方法,它们是:Invoke、BeginInvoke、EndInvoke 和 CreateGraphics。 在后台线程上创建控件的句柄之前调用 CreateGraphics 可能会导致非法的跨线程调用。 对于所有其他方法调用,则应使用调用 (invoke) 方法之一封送对控件的线程的调用。 调用方法始终在控件的线程上调用自己的回调。于是用下面的代码进行初步的测试:1.主线程调用Invoke 1 / 2 / 直接调用Invoke 3 / 4 private void TestInvoke() 5 6 listBox1.Items.Add(-begin-); 7 listBox1.Invoke(new Action() = 8 9 listBox1.Items.Add(Invoke);10 );11 12 Thread.Sleep(1000);13 listBox1.Items.Add(-end-);14 输出:从输出结果上可以看出,Invoke被调用后,是马上执行的。这点很好理解。2.主线程调用BeginInvoke 1 / 2 / 直接调用BeginInvoke 3 / 4 private void TestBeginInvoke() 5 6 listBox1.Items.Add(-begin-); 7 var bi = listBox1.BeginInvoke(new Action() = 8 9 /Thread.Sleep(10000);10 listBox1.Items.Add(BeginInvoke);11 );12 Thread.Sleep(1000);13 listBox1.Items.Add(-end-);14 输出:从输出能看出,只有当调用BeginInvoke的线程结束后,才执行它的内容。不过有两种情况下,它会马上执行:使用EndInvoke,检索由传递的 IAsyncResult表示的异步操作的返回值。 / / 调用BeginInvoke、EndInvoke / private void TestBeginInvokeEndInvoke() listBox1.Items.Add(-begin-); var bi = listBox1.BeginInvoke(new Action() = Thread.Sleep(1000); listBox1.Items.Add(BeginInvokeEndInvoke); ); listBox1.EndInvoke(bi); listBox1.Items.Add(-end-); 输出:同一个控件调用Invoke时,会马上执行先前的BeginInvoke / / 调用BeginInvoke、Invoke / private void TestBeginInvokeInvoke() listBox1.Items.Add(-begin-); listBox1.BeginInvoke(new Action() = Thread.Sleep(1000); listBox1.Items.Add(BeginInvoke); ); listBox1.Invoke(new Action() = listBox1.Items.Add(Invoke); ); listBox1.Items.Add(-end-); 输出:注:在主线程中直接调用Invoke、BeginInvoke、EndInvoke都会造成阻塞。所以应该利用副线程(支线线程)调用。3.支线线程调用Invoke创建一个线程,并在线程中调用Invoke,同时测试程序是在哪个线程中调用Invoke。 1 / 2 / 线程调用Invoke 3 / 4 private void ThreadInvoke() 5 6 listBox1.Items.Add(-begin-); 7 new Thread() = 8 9 Thread.CurrentThread.Name = ThreadInvoke;10 listBox1.Invoke(new Action() =11 12 Thread.Sleep(10000);13 this.listBox1.Items.Add(ThreadInvoke: + Thread.CurrentThread.Name); 14 );15 ).Start();16 Thread.Sleep(1000);17 listBox1.Items.Add(-end-);18 19 20 21 private void button1_Click(object sender, EventArgs e)22 23 Thread.CurrentThread.Name = Main;24 ThreadInvoke();25 26 27 private void button2_Click(object sender, EventArgs e)28 29 listBox1.Items.Add(button2_Click);30 输出:当点击button1后,我试图去点击button2,却发现程序被阻塞了。可见Invoke尽管在支线程中调用,实际上仍然在拥有此控件的基础窗口句柄的线程上执行。接着来测试下在支线程中调用BeginInvoke.4.支线线程调用BeginInvoke 1 / 2 / 线程调用BeginInvoke 3 / 4 private void ThreadBeginInvoke() 5 6 listBox1.Items.Add(-begin-); 7 new Thread() = 8 9 Thread.CurrentThread.Name = ThreadBeginInvoke;10 Thread.Sleep(10000);11 string temp = Before!;12 listBox1.BeginInvoke(new Action() =13 14 this.listBox1.Items.Add(temp + : + Thread.CurrentThread.Name);15 );16 temp += After!;17 ).Start();18 Thread.Sleep(1000);19 listBox1.Items.Add(-end-);20 21 22 23 private void button1_Click(object sender, EventArgs e)24 25 Thread.CurrentThread.Name = Main;26 ThreadBeginInvoke();27 28 29 private void button2_Click(object sender, EventArgs e)30 31 listBox1.Items.Add(button2_Click);32 输出:从这结果中我们能得出以下几点: 线程真正开始执行,是在创建它的线程结束后执行。 真正执行BeginInvoke的线程就是创建控件线程上。 BeginInvoke在线程中调用时,是异步执行的而且没有对主线程造成阻塞。(button2_Click在Before!After!:Main前面) BeginInvoke只有当创建它的线程结束后执行。(当然你也能通过EndInvoke、Invoke让其提早执行。) 总结:以下为了方便理解,假设如下:主线程表示Control.Invoke或Control.BeginInvoke中Control所在的线程,即创建该创建的线程。(一般为UI线程)支线程表示调用Invoke或BeginInvoke的线程。 Invoke、BeginInvoke始终在主线程中执行。 Invoke被调用时就会直接执行,也就是直接阻塞线程(包括主支线程),直到它结束。而BeginInvoke只有等支线程结束或者调用EndInvoke、Invoke时才会开始执行。 Invoke不管在哪里执行都会造成主线程的阻塞

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论