我有一个每10秒运行一次的队列:
Private Sub Form1Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
Dim t As New Timers.Timer(10000)
AddHandler t.Elapsed, New ElapsedEventHandler(AddressOf Elapsed)
t.Start()
End Sub
Private Sub Elapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs)
Dim timer1 As Timers.Timer = DirectCast(sender, Timers.Timer)
Try
' disable temporarily
timer1.Stop()
_quemanager.StartProcessing()
Thread.Sleep(1000)
Finally
' make sure that the handler is always reenables
timer1.Start()
End Try
End Sub
Namespace Managers
Public Class QueueManager
Private ReadOnly _items As New Queue
Public Sub StartProcessing()
For Each x In From i In File.GetAllAccountFolders() From x1 In File.CheckFolderForFiles(i & "\In") Select x1
_items.Enqueue(x)
Next
Dim t1 As New Threading.Thread(AddressOf Process)
t1.Start()
End Sub
Private Sub Process()
Do
SyncLock _items.SyncRoot
If _items.Count = 0 Then
'No more items.
Logger.Log("QueueManager", "Process", "No Items In Queue")
Exit Do
End If
Logger.Log("QueueManager", "Process", "Processing File: " & _items.Peek)
FileProcessingManager.ProcessFile(_items.Peek)
_items.Dequeue()
End SyncLock
Loop
End Sub
End Class
End Namespace
这背后的逻辑应该是计时器每隔10秒就会停止计时器运行队列,然后当队列结束时它应该再次启动计时器我想到这个吗?并且计时器无法重启其自身直到队列结束?
由于
答案 0 :(得分:1)
在您的示例代码中,QueueManager. StartProcessing
启动一个新线程,用于处理队列中的项目。这意味着它可能会在队列处理之前立即返回。然后,在timer elapsed事件处理程序中,在一秒钟的延迟后重新启动计时器。因此,如果队列需要超过一秒的时间来处理,那么在队列处理完成之前,计时器确实会重新启用。在这种情况下,我会完全删除那一秒睡眠,并在完成时QueueManager
引发一个事件。然后你的表单可以只注意那个事件,当它被引发时,它可以在事件处理程序中重新启用计时器。但是,在触摸计时器的属性之前,您需要先执行Me.Invoke
以返回UI线程。
Public Class Form1
Private WithEvents _quemanager As New QueueManager()
Private WithEvents _t As New Timers.Timer(10000)
Private Sub Form1Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
t.Start()
End Sub
Private Sub _t_Elapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs) Handles _t.Elapsed
' disable temporarily
_t.Stop()
_quemanager.StartProcessing()
End Sub
Private Sub _quemanager_ProcessingCompleted() Handles _quemanager.ProcessingCompleted
_t.Start()
End Sub
End Class
Public Class QueueManager
Private ReadOnly _items As New Queue
Public Event ProcessingCompleted()
Public Sub StartProcessing()
'...
End Sub
Private Sub Process()
Do
'...
Loop
RaiseEvent ProcessingCompleted()
End Sub
End Class