有没有类似的东西:Try Until?

Is there something like: Try Until?

我正在尝试让一个客户端尝试所有 5 秒来连接到不需要在线的服务器。只有在线时才应该连接。好吧,如果服务器已经在线并且客户端随后启动,则消息将毫无问题地发送。但如果客户端首先启动,它会等待一段时间直到超时并停止尝试连接。所以我试图用命令获得一个循环:

Client = New TCPControl2(ip,64555)

我试过这样做:

Try
Client = New TCPControl2(ip, 64555)
Catch ex As Exception
MsgBox(ex.Message)
End Try

我可以在 MsgBox 中找到有关超时的信息,但我不知道如何尝试直到它已连接或只是设置超时时间,但我也不知道。

Private Client As TCPControl2

继续尝试直到客户端连接到服务器? 如何使用 while 循环:

while(notConnected)
    Try
        Client = New TCPControl2(ip, 64555)
        notConnected= connectedState!="success"
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
end while

以下代码将尝试连接指定的秒数,如果成功则 return TCPControl2 对象。

Function TryConnect(ByVal ip As String, ByVal port As Integer) As TCPControl2
    While 1 = 1
        Try
            Dim client As New TCPControl2(ip, port)
            Return client
        Catch
        End Try
        Threading.Thread.Sleep(100)
    End While
    Return Nothing
End Function

用法:

    ' -- try to connect.. wait indefinitely
    Client = TryConnect(ip, 64555)
    If Client Is Nothing Then
        MsgBox("Unable to connect! Please check your internet connection.. blah blah.. whatever", MsgBoxStyle.Exclamation)
    Else
        ' you connected successfully.. do whatever you want to do here..
        'Client.WhaeverMethod()
    End If

在此处找到 C# 答案的翻译(归功于@LBushkin):Cleanest way to write retry logic?

我重命名了一些东西以使其更 VB 友好。我还将其更改为 return 如果按照评论中的建议所有重试都失败,则发现第一个异常:

Public Class Retry
    Public Shared Sub Invoke(action As Action, retryInterval As TimeSpan, Optional retryCount As Integer = 3)
        Invoke(Of Object)(Function()
                              action()
                              Return Nothing
                          End Function, retryInterval, retryCount)

    End Sub

    Public Shared Function Invoke(Of T)(action As Func(Of T), retryInterval As TimeSpan, Optional retryCount As Integer = 3) As T
        Dim firstException As Exception = Nothing
        For Retry = 0 To retryCount - 1
            Try
                Return action()
            Catch ex As Exception
                If firstException Is Nothing Then firstException = ex
                Threading.Thread.Sleep(retryInterval)
            End Try
        Next
        Throw firstException
    End Function

End Class

用法:

Retry.Invoke(Sub() SomeSubThatCanFail(), TimeSpan.FromMilliseconds(25))

Dim i = Retry.Invoke(Function() SomeFunctionThatCanFail(), TimeSpan.FromMilliseconds(25))

我认为您想要实现的目标可以通过 do while 循环来完成。您可以在这里阅读更多内容:https://msdn.microsoft.com/en-us/library/eked04a7.aspx

Dim isConnected As Boolean = false
Do
   Try
        Client = New TCPControl2(ip, 64555)
        ' Condition changing here.
       if Client.IsConnected = true ' <-- example!
           ' it's connected
           isConnected=true            
       end if
   Catch ex As Exception
        MsgBox(ex.Message)
   End Try
Loop Until isConnected = true