服务卡住并多次触发定时器

时间:2018-02-07 09:49:01

标签: .net vb.net multithreading timer

我在vb中创建了一个等待特定文件夹中的文件的Windows服务。如果有新文件,它将被扫描并移动到正确的文件夹。这项服务工作正常一个星期,然后发生了一些事情,我不知道为什么。服务卡住了50秒。计时器设置为10秒。

问题是计时器触发了代码读取和移动也是5次。我想你已经知道发生了什么。 5个线程试图读取并移动相同的文件并创建了一个异常战争。服务崩溃,必须手动重启。但我不能每天检查服务是否正在运行,所以我想改进一些东西。以下是我的代码的一些部分:

搜索文件:

Private Sub Listener_Tick(source As Object, e As ElapsedEventArgs)
    Try
        Dim al As New ArrayList
        SearchFiles("*.hl7", My.Settings.GetFolder, al)
        Dim FoundFile As String = ""
        Try
            FoundFile = al.Item(0)
        Catch ex As Exception
        End Try
        If FoundFile.Length = 0 Then
            If AtWork = True Then
                LogLine = "[INFO] No files left :) Service wait for files..." & FoundFile : WriteToLog()
                AtWork = False
            End If
        Else
            If AtWork = False Then
                LogLine = "[INFO] File(s) found. Work started!" : WriteToLog()
                AtWork = True

读取(不包括)和移动文件:

Try
    File.Move(FoundFile, FoundwithHL7)
    Catch ex As Exception
    LogLine = "[ERROR][EXCEPTION] HL7 import failed - " & hl7File & " - " & ex.ToString : WriteToLog()
End Try

是否有可能即使服务卡住了我也不会创建5个单独的线程?我认为布尔“AtWork”解决了这个问题,但如果5个不同的线程同时启动工作,情况并非如此。

2 个答案:

答案 0 :(得分:1)

1)U可以随时停止计时器直到工作完成。并恢复计时器

       Private Sub Listener_Tick(source As Object, e As ElapsedEventArgs)
        Listener.Enable = False ' u can alweys stop timer till task is not done
        Try
            '... Task
        Catch ex As Exception
        Finally
            Listener.Enable = True ' and resume at end
        End Try
    End Sub

2)如果你确定线程,你可以使用synhlock,所以只有一个线程可以同时执行方法。

        Private LockObj As New Object
    Sub DoSomthing()
        SyncLock LockObj ' Lock don't let other threat to work at this same time
            Try
                'Code Task
            Catch ex As Exception

            End Try
        End SyncLock
    End Sub
enter code here

3)U还可以使用文件Watcher在目录中新创建或编辑的文件上触发,不需要计时器 system.io.filesystemwatcher

答案 1 :(得分:0)

如果你一次只想要一个线程来执行某些活动,我通常会将一个线程专门用于该任务而不是设置一个计时器,然后担心重新入侵问题,就像你现在一样。 / p>

作为草图,您将拥有一个线程和某种形式的事件(以观察关闭)。你运行一个无限循环:

  1. 在变量中记录当前时间
  2. 进行处理工作
  3. 根据 now 的时间和您在步骤1中记录的时间以及当前用作计时器间隔的任何内容计算您想要睡多长时间。 1
  4. 使用步骤3中计算的时间作为超时值,而不是休眠,等待关机事件。
  5. 如果步骤4导致超时,则返回步骤1.否则,退出循环
  6. 1 E.g。如果从步骤1开始的时间是10:40,如果现在的时间是10:45,并且计时器间隔是10分钟,那么我们想要睡5分钟。如果计时器间隔是2分钟,那么我们当前的运行时间超过了,所以我们计算一个0分钟的睡眠间隔。我们仍然在第4步中执行等待步骤,以便关闭仍然可以有序地进行。