我在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个不同的线程同时启动工作,情况并非如此。
答案 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 E.g。如果从步骤1开始的时间是10:40,如果现在的时间是10:45,并且计时器间隔是10分钟,那么我们想要睡5分钟。如果计时器间隔是2分钟,那么我们当前的运行时间超过了,所以我们计算一个0分钟的睡眠间隔。我们仍然在第4步中执行等待步骤,以便关闭仍然可以有序地进行。