Лучшая практика консольного приложения c# для многократной проверки связи веб-api до тех пор, пока не будет возвращено определенное значение

У меня есть консольное приложение C#, которое обычно устанавливается как служба Windows, но также может быть запущено в консольном режиме (это не важно для вопроса, а просто дает контекст). Когда программа запускается, она отправляет запрос к веб-API для получения данных о том, как настроить программу. Если данных, которые он ищет, нет, я хотел бы, чтобы он периодически проверял связь с API на случай, если API в конечном итоге получит свои данные конфигурации.

Мне интересно, как лучше всего это сделать. Вот краткая версия того, что я имел в виду:

Stopwatch sw = Stopwatch.StartNew();
var response = null;
while (true)
{
    // Every 60 seconds, ping API to see if it has the configuration data.
    if (sw.Elapsed % TimeSpan.FromSeconds(60) == 0)
    {
        response = await PingApi();
        if (this.ContainsConfigurationData(response))
        {
            break;
        }
    }
}
this.ConfigureProgram(response);

Ничего другого в программе не происходит без этих данных конфигурации, поэтому кажется, что было бы нормально использовать цикл while и секундомер, как это? Однако я не уверен, что это лучшая практика. Я также не уверен, следует ли мне устанавливать ограничение на количество попыток, и что должно произойти, если этот предел будет достигнут. И вместо секундомера (или в дополнение к секундомеру) использовать Thread.Sleep?

Вот так вы будете использовать 100% -ный цикл ЦП.

tkausl 13.09.2018 19:20

Создайте таймер, который запускается с заданным интервалом, и сделайте свою проверку

Nkosi 13.09.2018 19:20

Во-первых, мне очень нравится Верхняя полка для таких сценариев.

Guru Stron 13.09.2018 19:21

Спасибо за комментарии. Думаю, я попробую использовать таймер, как предлагал Нкоси.

Drew 13.09.2018 19:55
0
4
173
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот пример использования таймера.

var timer = new System.Timers.Timer();

timer.Interval = TimeSpan.FromSeconds(60).TotalMilliseconds;
timer.Elapsed += async (sender, e) => 
{
    timer.Stop();

    var response = await PingApi();

    if (ContainsConfigurationData(response))
    {
        ConfigureProgram(response);
    }
    else
    {
        timer.Enabled = true;
    }
};
timer.Enabled = true;

Console.WriteLine("Press any key to continue...");
Console.ReadKey();

Похоже, это должно сработать, спасибо. Когда вызывается ConfigureProgram, я хочу, чтобы таймер перестал работать и вызывать истекшую функцию. Это происходит из-за того, что timer.Enabled = true помещается в корпус else? Интересно, а почему после функции стоит timer.Enabled = true. Я заметил, что Timer реализует IDisposable; возможно, его следует обернуть в оператор using? Или я могу вызвать timer.Dispose() напрямую после ConfigureProgram?

Drew 13.09.2018 20:34

Вы можете вызвать timer.Dispose () сразу после ConfigureProgram.

Hector Montero 13.09.2018 20:43

timer.Stop () находится в начале функции, чтобы после срабатывания каждого таймера ждать, получить ответ и подтвердить, а затем снова подождать 60 секунд (интервал), не принимая во внимание время ожидания в прошедшей функции.

Hector Montero 13.09.2018 20:47

Другие вопросы по теме