我就不多说了。 现在再来分析一下问题二, 其实例子比较明显, 是通过构造函数和属性来完成参数和返回值, 这一点我也不多说了。如果线程参数比较多的话,可以考虑属性来完成,类似于返回值。 问题三,我就更不用多说了。有人说了,如果子线程中的循环不能睡眠怎么办,因为睡眠的 话,有时会造成数据丢失,这方面的可以借鉴前面 Suspend 的做法,如果更复杂,则牵扯到 多线程的同步问题,这部分我会稍后单独写一篇文章。
前三个问题解决了,该说说最常见的问题,如何在子线程中控制窗体控件。这也是写线程方 面
程序经常遇到的,其实我以前写过两篇文章,都对这方面做了部分介绍。那么大家如果有 时间的话,不妨去看看。 blog.csdn.net/knight94/archive/2006/03/16/626584.aspx blog.csdn.net/knight94/archive/2006/05/27/757351.aspx 首先说说,为什么不能直接在子线程中操纵 UI 呢。原因在于子线程和 UI 线程属于不同的 上下文,换句比较通俗的话说,就好比两个人在不同的房间里一样,那么要你直接操作另一 个房间里的东西,恐怕不行
罢,那么对于子线程来说也一样,不能直接操作 UI 线程中的对 象。 那么如何在子线程中操纵 UI 线程中的对象呢,.Net 提供了 Invoke 和 BeginInvoke 这两种方 法。简单地说,就是子线程发消息让 UI 线程来完成相应的操作。 这两个方法有什么区别,这在我以前的文章已经说过了,Invoke 需要等到所调函数的返回, 而 BeginInvoke 则不需要。 用这两个方法需要注意的,有如下三点: 第一个是由于 Invoke 和 BeginInvoke 属于 Control 类型的成员方法,因此调用的时候,需要 得到 Control 类型的对象才能触发,也就是说你要触发窗体做什么操作或者窗体上某个控件 做什么操作,需要把窗体对象或者控件对象传递到线程中。 第二个,对于 Invoke 和 BeginInvoke 接受的参数属于一个 delegate 类型,我在以前的文章中 使用的是 MethodInvoker,这是.Net 自带的一个 delegate 类型,而并不意味着在使用 Invoke 或者 BeginInvoke 的时候只能用它。参看我给的第二篇文章( 《如何弹出一个模式窗口来显 示进度条》,会有很多不同的 delegate 定义。 ) 最后一个,使用 Invoke 和 BeginInvoke 有个需要注意的,就是当子线程在 Form_Load 开启 的时候,会遇到异常,这是因为触发 Invoke 的对象还没有完全初始化完毕。处理此类问题, 在开启线程之前显式的调用“this.Show();” ,来使窗体显示在线程开启之前。如果此时只是 开启线程来初始化显示数据,那我建议你不要使用子线程,用 Splash 窗体的效果可能更好。 这方面可以参看如下的例子。 syncfusion/FAQ/WindowsForms/FAQ_c95c.aspx#q621q 线程的四个相关问题已经说完了,这篇文章只说了单线程,以及单线程与 UI 线程交互的问 题。其中涉及到的方法不一定是唯一的,因为.Net 还提供了其他类来扶助线程操作,这里就 不一一罗列。至于多线程之间的同步,我会稍后专门写篇文章进行描述。