Public Overloads Sub New(ByVal myEvent As ManualResetEvent)
MyBase.New()
ResetEvent = myEvent
End Sub
Public Overloads Sub New(ByVal myEvent As ManualResetEvent, ByVal Name As String)
MyBase.New()
ResetEvent = myEvent
ThreadName = Name
End Sub
End Class
Private mstrMachine As String
Private mstrQueue As String
Private mWorkItems As Integer = 7
Private mFinished As Boolean = False
Dim mEvs() As ManualResetEvent
Public Property WorkItems() As Integer
Get
Return mWorkItems
End Get
Set(ByVal Value As Integer)
If Value > 15 Then
mWorkItems = 15
Else
mWorkItems = Value
End If
End Set
End Property
Public Sub New(ByVal Machine As String, ByVal Queue As String)
' Constructor accepts the necessary queue information
mstrMachine = Machine
mstrQueue = Queue
End Sub
Public Sub Listen(ByVal state As Object)
' Method that each thread uses to listen for messages
' Create a MessageQueue object
Dim objMQ As System.Messaging.MessageQueue = New System.Messaging.MessageQueue()
' Create a Message object
Dim objMsg As System.Messaging.Message ' = New System.Messaging.Message()
' Event from the state
Dim evs As ManualResetEvent
' Cast the state into the event
evs = state.ResetEvent
' Set the priority and name
Thread.CurrentThread.Priority = ThreadPriority.BelowNormal
Try
If Not state.ThreadName Is Nothing Then
Thread.CurrentThread.Name = state.ThreadName
End If
Catch e As Exception
' Thread name can only be set once
' Don't set it and get out
End Try
'Console.WriteLine("Listen {0} ", state.ThreadName)
Try
' Set the path property on the MessageQueue object, assume private in this case
objMQ.Path = mstrMachine & "\private$\" & mstrQueue
' Repeat until Interrupt received
While True
Try
' Sleep in order to catch the interrupt if it has been thrown
Thread.CurrentThread.Sleep(100)
' Set the Message object equal to the result from the receive function
' Will block for 1 second if a message is not received
objMsg = objMQ.Receive(New TimeSpan(0, 0, 0, 1))
' Message found so signal the event to say we're working
evs.Reset()
' Processing the message
ProcessMsg(objMsg)
' Done processing
Catch e As ThreadInterruptedException
' Catch the ThreadInterrupt from the main thread and exit
Exit While
Catch excp As MessageQueueException
' Catch any exceptions thrown in receive
' Probable timeout
Finally
' Console.WriteLine("Setting Event " & Thread.CurrentThread.GetHashCode())
' Done with this iteration of the loop so set the event
evs.Set()
End Try
' If finished then exit thread
If mFinished Then
'console.WriteLine("exiting " & thread.CurrentThread.GetHashCode)
Exit While
End If
End While
Catch e As ThreadInterruptedException
' Catch the ThreadInterrupt from the main thread and exit
End Try
End Sub
Private Sub ProcessMsg(ByVal pMsg As Message)
' Here is where we would process the message
End Sub
Public Sub Monitor()
Dim intItem As Integer
Dim objState As EventState
ReDim mEvs(mWorkItems)
mFinished = False
'Console.WriteLine("Queuing {0} items to Thread Pool", mWorkItems)
For intItem = 0 To mWorkItems - 1
'Console.WriteLine("Queue to Thread Pool {0}", intItem)
mEvs(intItem) = New ManualResetEvent(False)
objState = New EventState(mEvs(intItem), "Worker " & intItem)
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf Me.Listen), _ objState)
Next
End Sub
Public Sub Finish(Optional ByVal pTimeout As Integer = 0)
'Console.WriteLine("Waiting for Thread Pool to drain")
' Make sure everyone gets through the last iteration
mFinished = True
' Block until all have been set
If pTimeout = 0 Then
WaitHandle.WaitAll(mEvs) ' Waiting until all threads signal that they are done.
Else
WaitHandle.WaitAll(mEvs, pTimeout, True)
End If
'Console.WriteLine("Thread Pool has been drained (Event fired)")
End Sub
End Class
要注意该列表包含有两个类:EventState,它是一个protected的子类,还有QueueListener。EventState包含有一个称为ResetEvent的字段,它的类型是ManualResetEvent,用来确保所有的工作线程可以无中断地完成它的工作,这是通过使用ResetEvent字段得到其状态。该类还包含有一个ThreadName字段,用来设置与该类相关的线程的名字,以便作调试用。
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!



