2010-08-19 82 views
3

我平時做這樣的事情的陳述更好的辦法:重試拋出一個異常在vb.net

Dim Attempts = 0 
    Try 
Retry: 
     <Block> 
    Catch 
     If Attempts < 3 Then 
      Attempts += 1 
      Thread.Sleep(2000) 
      GoTo Retry 
     Else 
      Throw 
     End If 
    End Try 

這是非常糟糕的找我,但我不知道一個更好的方式正在做。

回答

1

我認爲這是一個不好的用法,我用這一個,它更乾淨。

Dim maxAttempt As Integer = 2 

For i As Integer = maxAttempt To 0 Step -1 

Try 
    ... 
    'Successful Quit 
    Exit For 

    Catch 
    Thread.Sleep(2000) 

    End Try 
Next 
+1

請注意,即使在應該傳遞異常的最後一次嘗試中,您也會默默捕捉所有異常。在for循環中只捕獲一個非常特定的異常(由於瞬態錯誤而引發的異常)也會更好。例如,你不想重試'ArgumentException'。 – 2010-08-19 09:15:29

+0

但我如何拋棄最後一個異常?這是很重要的 – ariel 2010-08-19 09:16:54

+0

好吧,我可以做「如果我= 0然後拋出」裏面的捕獲.. – ariel 2010-08-19 09:17:49

2

只需使用For循環或While循環而不是GoTo即可獲得成功。但除此之外,這是正確的方法。

+0

@Job Skeet:如果.NET語言有這樣的結構,它會很好。 – 2010-08-19 09:03:03

+0

對不起,但我沒有看到如何做到這一點。循環會包含整個Try? – ariel 2010-08-19 09:05:41

1

一般而言,重試失敗的內容應該被認真考慮。通常報告錯誤並讓用戶決定會好得多。

雷蒙德陳給出了一個很好的例子,如何自動重試可能會導致不必要的問題,並給出了建議,以避免重試:

Take it easy on the automatic retries

+0

我同意。如果你捕捉到更具體的異常類型,那麼它就不是什麼問題。 – jeroenh 2010-08-19 09:11:09

2

從概念上講,這是正確的方法,雖然我不會捕獲每個異常,請參閱@ 0xA3的答案。

你可以使它有點從實際代碼中分離的重試邏輯,「漂亮」如:

Sub TryExecute(Of T As Exception)(ByVal nofTries As Integer, 
             ByVal anAction As Action) 
     For i As Integer = 1 To nofTries - 1 
      Try 
       anAction() 
       Return 
      Catch ex As T 
       Thread.Sleep(2000) 
      End Try 
     Next 
     ' try one more time, throw if it fails 
     anAction() 
    End Sub 

哪個然後可以使用像這樣:

TryExecute(Of SomeExceptionType)(3, Sub() 
             <Block> 
            End Sub()) 

這不僅會在VB 10中工作,如果你使用的是.Net 3.5/VB 9,你需要在一個單獨的函數中分開這個

+0

AFAIK你不能做Sub()在VB.NET 3.5的End Sub()嗎? – 2010-08-19 10:20:48

+0

@dr。邪惡這是正確的,因爲寫的代碼將只能在VB.Net 10(.Net 4) – jeroenh 2010-08-19 10:52:30

+0

工作哦,我看到,還沒有觸及VB.NET 10。很高興看到VB最終得到了匿名代表。 – 2010-08-19 14:07:03

3

你也可以嘗試以下操作:

Dim retryCount as Integer = 0 
Dim wasSuccessful as Boolean = False 

Do 
    Try 
     <statements> 
     'set wasSuccessful if everything was okay.' 
     wasSuccessful = True 
    Catch 
     retryCount +=1 
    End Try 
Loop Until wasSuccessful = True OrElse retryCount >=5 

'check if the statements were unsuccessful' 
If Not wasSuccessful Then 
    <do something> 
End If 

如果語句不成功,它將重試最多五次,但如果語句執行成功,它將立即退出循環。

+1

現在,如果您在捕獲特定異常的同時執行以下語句:'Catch ex as SpecificExceptionType:retryCount + = 1:End Try' 我喜歡這個解決方案,它似乎比遞歸重試或GoTo塊更優雅。 – 2010-08-19 09:42:35