C# Invoke
2015-05-28 14:55
253 查看
要在程序中实现在一个线程中添加tabPage的问题,但是tabControl实在主进程中建立的,所以在运行时报错:线程间操作无效: 从不是创建控件“tabControl1”的线程访问它。
然后在网上查,需要用Invoke,delegate。网上有很多关于这些的资料,有些写的挺好的,看了感觉挺明白。
下面这段是网上的:
Invoke或者BeginInvoke方法都需要一个委托对象作为参数。委托类似于回调函数的地址,因此调用者通过这两个方法就可以把需要调用的函数地址封送给界面线程。这些方法里面如果包含了更改控件状态的代码,那么由于最终执行这个方法的是界面线程,从而避免了竞争条件,避免了不可预料的问题。如果其它线程直接操作界面线程所属的控件,那么将会产生竞争条件,造成不可预料的结果。
使用Invoke完成一个委托方法的封送,就类似于使用SendMessage方法来给界面线程发送消息,是一个同步方法。也就是说在Invoke封送的方法被执行完毕前,Invoke方法不会返回,从而调用者线程将被阻塞。
使用BeginInvoke方法封送一个委托方法,类似于使用PostMessage进行通信,这是一个异步方法。也就是该方法封送完毕后马上返回,不会等待委托方法的执行结束,调用者线程将不会被阻塞。但是调用者也可以使用EndInvoke方法或者其它类似WaitHandle机制等待异步操作的完成。
但是在内部实现上,Invoke和BeginInvoke都是用了PostMessage方法,从而避免了SendMessage带来的问题。而Invoke方法的同步阻塞是靠WaitHandle机制来完成的。
我一开始是直接在线程里添加tabpage,下面这样,然后就报错
后来用invoke
在线程中就这两句,将上面的操作卸载了addPage函数里,当然在一开始要声明public delegate void MyInvoke();
然后在网上查,需要用Invoke,delegate。网上有很多关于这些的资料,有些写的挺好的,看了感觉挺明白。
下面这段是网上的:
Invoke或者BeginInvoke方法都需要一个委托对象作为参数。委托类似于回调函数的地址,因此调用者通过这两个方法就可以把需要调用的函数地址封送给界面线程。这些方法里面如果包含了更改控件状态的代码,那么由于最终执行这个方法的是界面线程,从而避免了竞争条件,避免了不可预料的问题。如果其它线程直接操作界面线程所属的控件,那么将会产生竞争条件,造成不可预料的结果。
使用Invoke完成一个委托方法的封送,就类似于使用SendMessage方法来给界面线程发送消息,是一个同步方法。也就是说在Invoke封送的方法被执行完毕前,Invoke方法不会返回,从而调用者线程将被阻塞。
使用BeginInvoke方法封送一个委托方法,类似于使用PostMessage进行通信,这是一个异步方法。也就是该方法封送完毕后马上返回,不会等待委托方法的执行结束,调用者线程将不会被阻塞。但是调用者也可以使用EndInvoke方法或者其它类似WaitHandle机制等待异步操作的完成。
但是在内部实现上,Invoke和BeginInvoke都是用了PostMessage方法,从而避免了SendMessage带来的问题。而Invoke方法的同步阻塞是靠WaitHandle机制来完成的。
我一开始是直接在线程里添加tabpage,下面这样,然后就报错
TabPage tp = new TabPage(); tp.Name = str.Substring(2); tp.Text = str_in.Substring(1); ListView lv = new ListView(); lv.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControl1.Controls.Add(tp); tp.Controls.Add(lv)
后来用invoke
在线程中就这两句,将上面的操作卸载了addPage函数里,当然在一开始要声明public delegate void MyInvoke();
MyInvoke mi = new MyInvoke(addPage); this.BeginInvoke(mi);
private void addPage() { TabPage tp = new TabPage(); tp.Name = str.Substring(2); tp.Text = str_in.Substring(1); //ListView lv = new ListView(); //lv.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControl1.Controls.Add(tp); //tp.Controls.Add(lv); }
相关文章推荐
- c#调用COM组件
- C#中抽象方法与虚拟方法的区别
- c#中虚函数的相关使用方法
- C#实现多线程的同步方法实例分析
- C#中尾递归的使用、优化及编译器优化
- C#通用邮件发送类分享
- C#中Equality和Identity浅析
- C#生成饼形图及添加文字说明实例代码
- C#判等对象是否相等的方法汇总
- C#简单的向量用法实例教程
- C#托管堆对象实例包含内容分析
- C#实现按照指定长度在数字前补0方法小结
- C#虚方法的声明和使用实例教程
- C#获取文件夹及文件的大小与占用空间的方法
- C#定义简单的反射工厂实例分析
- C#数字图象处理之肤色检测的方法
- C#实现用于操作wav声音文件的类实例
- C#选择排序法实例分析
- C#线程间不能调用剪切板的解决方法
- C#实现WinForm捕获最小化事件的方法