UML软件工程组织
|
C#多线程应用探讨 |
作者:
王志喜 王润云 Thursday, September 18 2003 4:15 PM |
使用线程首先创建运行在新线程上的后台任务。表1所示的代码执行一个相当长的运行处理----一个无限循环。
这段代码无限循环,每次执行时在列表框中加入一个项目。 在规定好一个工作的处理代码以后,就需要将这段代码分配给一个线程,并且启动它。为此需要使用线程对象(Thread object),它是.NET架构类中System.Threading命名空间的一部分。在实例化一个新的线程类时,需要把在线程类构造器中执行的代码块的一个引用传送给该实例。表2所示的代码创建一个新的线程对象,并且将BackgroundProcess的一个引用传送给该对象。
ThreadStart表示在线程上执行的方法,这里是一个到BackgroundProcess方法的委派对象。在C#中,一个委派是一个类型安全、面向对象的函数指针。在实例化该线程后,可以通过调用线程的Start()方法来开始执行代码。 控制线程在线程启动以后,可以通过调用线程对象的方法来控制线程的状态。可以通过调用Thread.Sleep方法来暂停一个线程的执行,这个方法可以接收一个整型值,用来决定线程休眠的时间。对于本文的实例程序,为了让列表项目增加的速度变慢,在其中放入了一个Sleep方法的调用。 可以通过调用Thread.Sleep(System.Threading.Timeout.Infinite)来让线程进入休眠状态,但是,这个调用的休眠时间是不确定的。要中断这个休眠,可以调用Thread.Interrupt方法。 通过调用Thread.Suspend方法可以挂起线程。挂起可以暂停一个线程,直到另一个线程调用Thread.Resume为止。休眠和挂起的区别是,挂起并不立刻让线程进入一个等待的状态,线程并不会挂起,直到.NET runtime认为现在已经是一个安全的地方来挂起它了,而休眠则会立刻让线程进入一个等待的状态。
Thread.Abort方法可以停止一个线程的执行。本文的实例程序通过加入一个按钮button2来停止后台处理,在事件处理程序中调用了Thread.Abort方法,如表3所示。 这就是多线程的强大之处。用户界面的响应很快,因为用户界面运行在一个单独的线程中,而后台的处理运行在另外一个线程中。在用户按下按钮button2时,就会马上得到响应,并且停止后台处理。 通过多线程程序传送数据在实际工作中,还需要使用到多线程的许多复杂特性。其中一个问题就是如何将程序的数据由线程类的构造器传入或者传出。对于放到另外一个线程中的过程,既不能传参数给它,也不能由它返回值,因为传入到线程构造器的过程是不能拥有任何参数或者返回值的。为了解决这个问题,可以将过程封装到一个类中,这样,方法的参数就可使用类中的字段。 本文给出了一个简单的例子,计算一个数的平方。为了在一个新的线程中使用这个过程,将它封装到一个类中,如表4所示。 使用表5所示的代码在一个新的线程上启动CalcSquare过程。
在上述例子中,线程启动后,并没有检查类中的square值,因为即使调用了线程的start方法,也不能确保其中的方法马上执行完。要从另一个线程中得到需要的值,有几种方法,其中一种方法就是在线程完成的时候触发一个事件。表6所示的代码为SquareClass加入了事件声明。
对于这种方法,要注意的是事件处理程序SquareEventHandler运行在产生该事件的线程t2中,而不是运行在窗体执行的线程中。 同步线程在线程的同步方面,C#提供了几种方法。在上述计算平方的例子中,需要与执行计算的线程同步,以便等待它执行完并且得到结果。另一个例子是,如果在其它线程中排序一个数组,那么在使用该数组前,必须等待该处理完成。为了实现同步,C#提供了lock声明和Thread.Join方法。 lock声明
lock可以得到一个对象引用的唯一锁,使用时只要将该对象传送给lock就行了。通过这个唯一锁,可以确保多个线程不会访问共享的数据或者在多个线程上执行的代码。要得到一个锁,可以使用与每个类关联的System.Type对象。System.Type对象可以通过使用typeof运算得到,如表7所示。 Thread.Join方法
Thread.Join方法可以等待一个特定的时间,直到一个线程完成。如果该线程在指定的时间内完成了,Thread.Join将返回True,否则它返回False。在上述平方的例子中,如果不想使用触发事件的方法,可以调用Thread.Join的方法来确定计算是否完成了。代码如表8所示。 结论本文通过一个实例程序说明了C#中线程的使用和控制方法,探讨了如何通过多线程程序传送数据和线程的同步问题。根据本文的分析可知,在C#中,使用线程是很简单的。C#支持建立自由线程的应用,提高了资源的利用率,程序的响应速度也得到了改善。当然也带来了数据传送和线程同步等问题。 参考文献[1] 袁鹏飞,C#和.NET架构[M],人民邮电出版社,北京,2002年4月第1版,123-125 [2] 麦中凡等,C#编程语言[M],北京航空航天大学出版社,北京,2001年8月第1版,286-291 [3] 微软公司、东方人华,C#语言参考手册[M],清华大学出版社,北京,2001年7月第1版,271-274 [4] 李太君、张树亮,利用Visual Basic.Net开发多线程应用程序[J],现代计算机,2002年第11期 [5] 邱艳宇等,VB.NET多线程在数据采集与处理系统中的应用[J],微型机与应用,2002年第08期 湖南省自然科学基金(编号:02JJY4045)资助项目 作者简介:王志喜,男,1970年生,硕士,湖南科技大学计算机学院副教授,主要研究方向为:面向对象技术,软件工程等。王润云,1960年生,女,湖南科技大学计算机学院副教授,主要研究方向为:程序设计语言,面向对象技术,计算机辅助设计等。
|
版权所有:UML软件工程组织 |