0

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秒ごとに経過するとタイマーが停止し、キューが実行され、キューが終了すると再びタイマーを開始する必要があるということです。キューが終了するまで、タイマーが自己を再起動する方法はありませんか?

ありがとう

4

1 に答える 1

1

コード例QueueManager. StartProcessingでは、キュー内のアイテムを処理する新しいスレッドを開始します。つまり、おそらくキューが処理される前に、すぐに返されます。次に、タイマー経過イベント ハンドラーで、1 秒の遅延後にタイマーを再起動します。そのため、キューの処理に 1 秒以上かかる場合、キューの処理が完了する前にタイマーが再度有効になります。この状況では、その 1 秒間のスリープを完全に削除し、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
于 2012-07-13T12:09:50.227 に答える