注:Jon Rauschenberger于9月18日在Orlando的VBITS上发表了“Threading with .NET”。本篇技巧选自那次大会的材料。
.NET Framework给所有开发人员提供了强大的线程工具——不管他们运用的是何种语言。VB开发人员首次可以很容易地创建多线程的应用程序,这些应用程序充分利用了Windows平台的线程功能。运用该功能是相当简单的。例如下面这个类:
clearcase/" target="_blank" >cc>Public Class Worker Public Sub DoSomeWork() Thread.Sleep(1000) End Sub End Class |
这个简单的类包含一个单独的方法,它通过使处于“active”状态的线程休眠一秒钟来模拟一件长期运行的任务。如果你需要多次调用该方法,你可以大量生成多个线程并在每个单独的线程上调用该方法。你需要写多线程的代码的所有的类都在System.Threading名字空间中。要运用这些类,你可以用下面的代码来导入该名字空间:
Imports System.Threading |
如果你需要调用DoSomeWork方法100次,你可以用下面的代码:
For currentWorkItem = 1 To 100 Dim currentWorker As New Worker() Dim currentThreadStart As New _ ThreadStart( _ AddressOf currentWorker.DoSomeWork) Dim newThread As New _ Thread(currentThreadStart) newThread.Start() Next |
该代码会为每个请求生成一个新的线程,然后在线程中运行DoSomeWork方法。该代码的问题是你会生成100个线程来处理100个调用。每个CPU生成的线程超过了25个就会严重影响效率。在执行多个线程时,操作系统必须为每个线程安排处理时间。你生成的线程越多,OS就必须花更多的时间为每个线程安排CPU处理时间,CPU用来执行每个线程所做工作的时间就越少。
为了解决这个问题,.NET Framework提供了一个系统线程池,你可以在里面将任务列队。线程池中包含一系列线程,它们处理内部任务队列中的请求。缺省情况下,线程池中的最多线程数量是每个CPU 25个。这就是说,不管你在任务队列中放置了多少请求,所生成的线程数量永远不会超过CPU的数量乘以25。要运用系统线程池来调用DoSomeWork方法100次,你可以用ThreadPool.QueueUserWorkItem方法。该方法将一个委派(delegate)作为一个输入参数。当工作线程将一项任务从队列中取出时,线程将调用委派,并运行你的代码。
运用系统线程池的第一步就是用下面的代码创建你想让线程执行的方法:
Private Sub CallDoWork(ByVal State As Object) Dim currentWorker As New Worker() currentWorker.DoSomeWork() Me.pgbStatus.Value += 1 End Sub |
该方法的定义必须与System.Threading.WaitCallback委派的定义相符。在VB语法中,这就是说,该方法必须被声明为一个Sub,它采用一个单独的叫做State的Object参数。接下来,你只需要调用ThreadPool.QueueUserWorkItem方法,传入CallDoWork方法的地址:
For currentWorkItem = 1 To 100 Dim threadQueueCallback As New _ WaitCallback(AddressOf CallDoWork) ThreadPool.QueueUserWorkItem( _ threadQueueCallback) Next |
注意,ThreadPool这个类是静态的,所以你不需要创建它的一个实例——你可以只运用它。在运行该代码时,100条任务会被放在线程池的任务队列上。然后CLR通过监控队列中任务数量来管理队列中的线程数量。在一个单个CPU机器上,会很快生成25个线程并添加到系统线程池中,但这个数量不会超过25个。
运用系统线程池可以让你控制你的应用程序将会生成的线程数量。对于一些你不能控制的情况(如到达队列的消息或调用一个Web service的用户),能够控制线程数量就显得很重要了。运用线程池就可以让你确保你的应用程序的行为是可以预测的,即使它处理的负荷在不断增加。
关于作者:
Jon Rauschenberger是Clarity的合作伙伴以及技术主管,这是一家位于芝加哥的信息技术咨询公司,也是Microsoft Solution Provider Partner。Jon经常在大会上发言并为期刊投稿。另外,作为Microsoft的Strategic Design Review委员会的成员,Jon帮助Microsoft Visual Studio及平台组来策划他们的产品的未来。Jon的联系方式是jrausch@claritycon.com。