博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

多线程应用程式中调用窗体的一点心得-.NET教程,算法/线程

Posted on 2008-09-12 16:36  chgBlog  阅读(205)  评论(0)    收藏  举报
昨天自己编写一个多线程的程式,主要作用是tcp通迅的小程式,里面使用了多线程的技术,碰到一个有趣的问题:就是在工作线程中我调用了一个窗体,让他显示出来。如form1 f=new form1();f.show();这种代码平时一点问题都没有。但是在工作线程中却无法调过了。我的form1在桌面上动弹不得了。什么也不响应。有点象假死机的状态。后来我将form1 f;这代码放到主线程里去实例化,一切都正常了。(估计是工作线程的原因)

经过查阅msdn才知道:

当程式运行时,我们已开启了一个线程,ui 线程. 而平时的一般工作,比如说新开窗口啦,按钮事件啦,这都是在ui 线程的管辖之下。而假如我们新建一个线程,当这个线程需要调用一个新窗口的时候,不能够直接在这个新线程之下调用,而是需要让ui 线程去调用新窗口。而新的线程所做的是给ui线程发送一条信息,让他打开窗口。而做这一步,我们就需要用到delegate 技术。 假如一个控件的处理程式和操作他的代码不在同一线程中,则需要使用 控件名.invoke 方法


代码片断如下:

//工作线程的代码将直接调用form下定义的formshow方法

listenerthread()

{

//这是个自由线程。不能在这里直接调用一个窗体

formshow();//ok

}

delegate void formhandler(dataset ds);//声明一个委托

//定义一个方法此方法用来显示一个窗体

private void formshow(dataset ds)
{
if (!this.invokerequired) //假如当前线程不是主ui线程,返回true,否则,返回false.
{
frmbills fb = new frmbills();
fb.show();
fb.display(ds);
}

else

{
formhandler fhandler = new formhandler(this.formshow); //创建一个新instance指向formshow.
this.invoke(fhandler, new object[] {ds}); //启动delegate
}