我的vb.net服务有一个定时器,每分钟左右滴答一次,但在执行之前检查前一个线程是否已经完成(我不想重复结果)
问题是,在某些时候,进程只是挂起进程,所以我写道如果进程在5分钟内没有完成,它应该继续执行。
现在我在应用程序中有一些挂起的线程......无所事事地吃资源。
所以我的问题是我是否可以杀死这些线程。
Protected Overrides Sub OnStart(ByVal args() As String)
EmailTimer = New System.Timers.Timer(50000)
EmailTimer.AutoReset = True
AddHandler EmailTimer.Elapsed, AddressOf CheckNewEmails
EmailTimer.Start()
End Sub
工人代码:
Private Sub CheckNewEmails(ByVal sender As Object, e As System.Timers.ElapsedEventArgs)
If _workStartTime <> DateTime.MinValue Then
' check how much time has elapsed since work started previously
If DateDiff(DateInterval.Minute, _workStartTime, Now) > 5 Then
_workStartTime = DateTime.MinValue
End If
Else
_workStartTime = DateTime.Now
Dim client As New ImapClient()
client.Connect("imap.gmail.com", 993) 'that line could sleep forever..
End if
_workStartTime = DateTime.Now
End Sub
答案 0 :(得分:2)
你的client.Connect
可能没有挂起,而是抛出一个异常,它逃脱你的异常处理程序,被Timer
对象本身压扁,而你却不是更聪明。那是因为System.Timers.Timer
压扁了异常。你应该在你的处理程序周围放一个Try ... Catch ... Finally
,如下所示:
Private Sub CheckNewEmails(ByVal sender As Object, e As System.Timers.ElapsedEventArgs)
If _workStartTime <> DateTime.MinValue Then
' check how much time has elapsed since work started previously
If DateDiff(DateInterval.Minute, _workStartTime, Now) > 5 Then
_workStartTime = DateTime.MinValue
End If
Else
Try
_workStartTime = DateTime.Now
Dim client As New ImapClient()
client.Connect("imap.gmail.com", 993) 'that line could sleep forever..
Catch ` whatever exception
` log exception here
Finally
' cleanup
End Try
End if
_workStartTime = DateTime.Now
End Sub
这至少会告诉你Connect
是否真的悬空,或者它是否正在抛出被抑制的异常。
另请参阅我对_workStartTime
的评论。我没有看到它回到DateTime.MinValue
的位置,这肯定会导致你描述的问题。
如果对Connect
的呼叫确实挂起并且没有可以让您设置超时的呼叫,那么您需要找到一个新的IMAP客户端,因为该客户端无法挽回地被破坏。克服构造不良的库的局限性从来都不是一个好主意。
对于您的计时器,不是设置一分钟计时器并检查是否已经处理了一个计时器,而是将计时器设置为单次计时器,并在计时器完成处理后重置计时器。这样就无法获得多个并发滴答。所以你的计时器初始化看起来像这样:
EmailTimer = New System.Timers.Timer(50000)
EmailTimer.AutoReset = False ' Don't want auto reset!
AddHandler EmailTimer.Elapsed, AddressOf CheckNewEmails
EmailTimer.Start()
你的经纪人:
Private Sub CheckNewEmails(ByVal sender As Object, e As System.Timers.ElapsedEventArgs)
Try
Dim client As New ImapClient()
client.Connect("imap.gmail.com", 993) 'that line could sleep forever..
Catch ' whatever exceptions you want to catch
' log exception
Finally
' Now set the next timer interval.
EmailTimer.Start()
End Try
End Sub
这不会每50秒做一次。相反,它会在上一个滴答完成后50秒进行勾选。
答案 1 :(得分:0)
虽然@Jim Mischel的回答非常有帮助,但我仍然希望添加自己的答案来解决我的问题。
经过大量挖掘后,我发现问题只是因为资源没有得到妥善处理......
将sub包含在using子句中后,问题就消失了。
我希望将来可以帮助某人......