退出服务中的其他线程

时间:2014-03-03 20:21:37

标签: .net vb.net multithreading service

我的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

2 个答案:

答案 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子句中后,问题就消失了。

我希望将来可以帮助某人......