手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网络编程>Asp.Net编程>列表

用Visual Basic.Net创建多线程应用程序

来源:互联网 作者:西部数码 时间:2008-04-09
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

Return
End Sub
  很明显,critical sections仅应该在需要的时候创建,因为它们会阻塞线程,从而会影响整体的吞吐量。

  要同步线程间共享的实例变量,有一个很简单的技巧,这就是使用Interlocket类。该类包含有共享的Increment和Decrement方法,可以将修改变量和检查结果的操作结合成一个单一的操作。这样做是必需的,因为一个线程可以修改变量的值,在接着检查结果之前,它的运行时间就结束了。在该线程再次运行时,变量的值就有可能被其它的线程修改了。

  例如下面的代码增加Instructors类的mPhotosProcessed实例级变量的值:

Interlocked.Increment(mPhotosProcessed)
  Interlocked类还支持Exchange和CompareExchange的方法,它们的作用分别是设置变量为特定的值,或者在该变量等于某个值时才这样做。
156
  使用线程本地存储

  虽然在理想的情况下你的线程将使用私有的实例变量,不过在许多时候,当你的线程运行一个对象的方法,而该方法可能被其它的线程共享时,这样你的线程可能需要存储和接收它自己的真正私有数据。例如,当一个线程池中的线程监视一个MSMQ队列,并且需要取得队列中数据,然后存储下来作以后处理用时,就会出现这种情形。

  在Windows操作系统中,每个线程都拥有自己的线程本地存储(thread local storage,TLS),以用来跟踪状态信息。方便的是,Thread类拥有一套方法,可方便地创建和维护TLS中的内存区域(该区域称为data slots)。

  值得一提的是,Thread类拥有一个共享的AllocateNamedDataSlot方法,可以使用指定的名字为AppDomain中的所有线程创建一个新的data slot。该slot可以在随后通过使用SetData和GetData方法设置和读取。例如,假定有一个称为WorkerClass类执行一些处理活动,并且我们想创建一定数量的线程来执行该工作。以下的代码段为所有的线程创建了一个称为“ID”的data slot,然后通过objWorker实例的StartWork方法,执行相应数量的线程:

Dim dssSlot As LocalDataStoreSlot
Dim tNew As Thread
Dim objWorker As WorkerClass

dssSlot = Thread.AllocateNamedDataSlot("ID")

For i = 0 to intMaxThreads
 tNew = New Thread(New ThreadStart(AddressOf objWorker.StartWork)
 tNew.Start
Next

  要注意的是由于所有的新线程将会共享objWorker上的实例变量,因此StartWorker方法和任何通过Start调用的方法将需要使用同步以防止对这些变量的同时访问。不过,如果每个线程需要它们自己的数据在方法间共享,它们可以将一个拷贝放到TLS的“ID”slot中,如下所示。

Public Sub Start()
 Dim dssIDSlot As LocalDataStoreSlot
 Dim myID As Integer

 ' Do other work

 dssIDSlot = Thread.GetNamedDataSlot("ID")
 Thread.SetData(dssIDSlot, myID)
 Call NextProcess()
End Sub

Private Sub NextProcess()
 Dim myID As Integer
 Dim dssIDSlot As LocalDataStoreSlot

 dssIDSlot = Thread.GetNamedDataSlot("ID")
 myID = Thread.GetData(dssIDSlot)

 ' Do other work
End Sub
  当NextProcess方法被调用时,数据可以再次通过使用Getdata由slot中读取。

  再次提醒一下,上面提到的设计模式在需要时才使用。只有在你的设计是很复杂而且需要从多个线程中访问同样的对象时,你才需要使用TLS。
  使用线程工具

  你可以通过Thread类来创建和管理自己的线程,System.Threading命名空间还提供了一个简单的方式来使用线程,这些线程由CLR分配的一个池得到。这样做是可能的,因为CLR自动在每个进程创建和管理一个线程池,这样做是为了用来处理异步的操作,例如I/O和事件。在池中,一个线程被分配Highest优先权利,它是用来监视队列中其它线程的状态的。使用ThreadPool类,你的代码可接进这个池,并且可以更有效地使用这个在运行时已经配置的体系。实际上,ThreadPool类可允许你提交工作项目(例如要执行的方法)到池中,它们会被随后的工作线程执行。

  如前所述,只有在应用需要的时候才使用线程,并且要经过仔细的分析。例如,使用线程池的一个很好的情形是,一个用来监听由一个或者多个信息队列中进入的新信息的Windows服务应用。虽然System.Messaging命名空间支持异步的操作,但是创建一个线程池可允许你控制一些特别的方面,例如有多少线程在处理信息和线程的生存时间。

  下面例子是一个经过简化的类,它使用ThreadPool类,用来监听一个MSMQ队列。

  列表11.9 QueueListener类,该类使用ThreadPool类来监听一个MSMQ队列

Option Strict Off

Imports System
Imports System.Threading
Imports System.Messaging
Imports Microsoft.VisualBasic

Public Class QueueListener
' Used to listen for MSMQ messages

 Protected Class EventState
 ' Used to store the event and any other state data required by the listener
  Public ResetEvent As ManualResetEvent
  Public ThreadName As String

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!