2014-03-03 41 views
1

我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

順便說一句,在你的'else'套'_workStartTime = DateTime.Now'最後一次。我沒有看到它回到'DateTime.MinValue'的位置。如果這是實際的運行代碼,那麼很可能是問題的原因。 –

+0

對不起,它是一個錯字,這是在刪除大量不相關的句子時發生的。它實際上將時間重置爲minValue。 – Ezi

回答

0

雖然@Jim Mischel的回答非常有幫助,但我仍然想添加自己的答案,以解決我的問題。

經過大量挖我的發現,這個問題很簡單,因爲資源沒有得到妥善處置......

一個使用條款中封閉子後,問題消失。

我希望這將幫助別人的未來...

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秒內打勾。

+0

非常感謝所有有用的評論,我確實在服務上調用了調試器,並且我發現它是掛起的,(通常只發生在一夜之間,我搜索了另一個免費的imap/pop閱讀器庫,但是還沒找到,所以現在我需要破解它... – Ezi

+0

我之前使用過autoReset = False,但是由於read子卡住了,定時器從未回頭。這是一個大問題,這就是爲什麼我將定時器更改爲總是運行,然後檢查是否有掛接點。 – Ezi

+0

@Ezi:有很多IMAP客戶端可用,有些是免費的,有些不是。請參閱http://stackoverflow.com/q/670183/56778 –