client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
Если вы хотите отслеживать неудачные попытки и хотите сохранить хороший старый асинхронный шаблон, я бы передал объект состояния:
class ConnectionState {
Socket Client {get; set;}
int FailedAttempts {get; set;} = 0;
}
Тогда передайте это:
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), new ConnectionState(){ .Client = client, FailedAttempts = 0});
В обратном вызове:
private void ConnectCallback(IAsyncResult ar)
{
ConnectionState state = (ConnectionState)ar.AsyncState;
try
{
state.Client.EndConnect(ar);
}
catch (SocketException ex)
{
_logger.Info(ex.ToString());
if( state.FailedAttempts < MAX_ATTEMPTS )
{
state.FailedAttempts += 1;
state.Client.BeginConnect( remoteEP, new AsyncCallback(ConnectCallback), state );
// you may also check the exception for what happened exactly.
// There may be conditions where retrying does not make sense.
// See SocketException.ErrorCode
}
else
{
// You may want to handle exceeding max tries.
// - Notify User
// - Maybe throw a custom exception
}
}
}
Ссылка на коды ошибок SocketException: https://docs.microsoft.com/en-us/windows/desktop/winsock/windows-sockets-error-codes-2
Для настройки механизма повтора, основанного на времени, я бы создал своего рода «сторожевой таймер соединения»: каждые 10 секунд проверяйте поле клиента по таймеру. Если оно пустое, а попытка подключения еще не запущена, запустите ее.
Лично я бы попробовал переключиться на TPL . Но я считаю это альтернативой, а не прямым ответом на ваш вопрос. Но я рекомендую это.