Каков наилучший способ выйти из строя после тайм-аута?

#c# #algorithm

#c# #алгоритм

Вопрос:

Я новичок в C # и хочу создать алгоритм, который остановит подключение после некоторого значения тайм-аута.

 private void SetupConnection()
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();

    while (true)
    {
           try
            {
                ConnectToDataServer();
                break;
            }
            catch (SocketException)
            {
                if (stopwatch.Elapsed < _request.TransferTimeout)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(5));
                }
                else
                {
                    _request.TransferTimeout = new TimeSpan();
                    throw;
                }
            }
        }
    }
}
  

Хороший ли алгоритм для сбоя после тайм-аута? Если нет, как я могу это улучшить?

Комментарии:

1. Это лучше подходит для раздела CodeReview, потому что вы спрашиваете мнения и не имеете конкретной проблемы. В любом случае, вот мое мнение: поскольку время зависит от машины, на которой выполняется ваш код, я бы предпринял ограниченное количество попыток перед сбоем. Например, сервер получает 50 шансов ответить вашему клиенту, прежде чем клиент признает, что сервер не отвечает. Также убедитесь, что ваш цикл не замораживает графический интерфейс при повторных попытках. Я бы порекомендовал BackgroundWorker.

Ответ №1:

Используйте CancellationToken:

Распространяет уведомление о том, что операции должны быть отменены.

Рекомендуемым подходом было бы передать его вашему ConnectToDataServer методу:

 private void SetupConnection()
{
    CancellationTokenSource cancellation = new CancellationTokenSource();
    cancellation.CancelAfter(TimeSpan.FromSeconds(5));
    ConnectToDataServer(cancellation.Token);
}
  

При достижении времени ожидания будет вызвано исключение OperationCanceledException.

Вы ConnectToDataServer должны продолжать передавать аргумент, пока не сможете соответствующим образом обработать отмену.

Если вы используете стороннюю библиотеку внутри, API должен иметь перегрузку метода, принимающую a CancellationToken .


Если вы не можете изменить метод ConnectToDataServer

Тогда ваш лучший выбор — обернуть ваш вызов вокруг Task :

 private void SetupConnection()
{
    CancellationTokenSource cancellation = new CancellationTokenSource();
    cancellation.CancelAfter(TimeSpan.FromSeconds(5));
    Task.Run(() => ConnectToDataServer(), cancellation.Token).GetAwaiter().GetResult();
}