Замена Thread.Sleep на Task.Delay - PullRequest
       15

Замена Thread.Sleep на Task.Delay

0 голосов
/ 02 июля 2019

Я выполняю рефакторинг кода, который использует Thread.Sleep с возрастающим ограничением по времени, чтобы повторить запросы SQL в случае ошибок.Общая замена Thread.Sleep для блокировки, по-видимому, await Task.Delay, что потребовало изменения метода на async.Теперь метод выглядит следующим образом (дополнительная краткая проверка ошибок удалена для краткости):

    private static async Task<int> PrepareForRetry( int retryCount, SqlCommand command, int timeout )
    {
        ++retryCount;
        if (retryCount < ConnectionRetryCount)
        {
            int SleepTime = _connectionRetryBackoffTimes[retryCount - 1] + (_connectionRetryRandomBackoff.Next() % 500);
            //Thread.Sleep(SleepTime);
            await Task.Delay(SleepTime);
        }
        return retryCount;
    }

Проблема, с которой я сталкиваюсь, состоит в том, что async требует, чтобы вызывающий метод был async, и так далее.Хотя в конечном итоге рефакторинг становится полностью асинхронным, это выходит за рамки текущей области рефакторинга.

У меня проблема в том, как вызвать метод из синхронного кода и получить результат.Использование

retryCount = PrepareForRetry(retryCount, command, timeout).Result;

создает тупик, поскольку поток пользовательского интерфейса вызывает метод.Я видел, что могу решить эту проблему, изменив свой Task.Delay на

await Task.Delay(SleepTime).ConfigureAwait(false);

, но я не до конца понимаю, что это делает.Я также попытался вызвать метод, используя

retryCount = Task.Run(async () => { await PrepareForRetry(retryCount, command, timeout).Result; });

, но в нем есть ошибка "int" не содержит определения для GetAwaiter ", и я не смог выяснить, как яможно приступить к получению результата.Является ли использование Task.Delay правильным способом создания задержки (таймер не позволяет увеличить время ожидания), и если да, то как мне вызвать метод для получения возвращаемого значения?

1 Ответ

3 голосов
/ 02 июля 2019

Вы должны использовать тот же стиль для задержек, что и для реальной операции.Если ваш SqlCommand выполняется асинхронно, то используйте Task.Delay для задержек.Если ваш SqlCommand выполняется синхронно, тогда используйте Thread.Sleep для задержек.

Похоже, вам все еще нужно, чтобы ваш SqlCommand выполнялся синхронно (по крайней мере, на данный момент), поэтому вы должны использовать Thread.Sleep.В конце концов, вы можете сделать их обоих асинхронными (в то же время), но звучит так, как будто это работа на другой день.* замена на Thread.Sleep.Просто Task.Delay является асинхронным эквивалентом из Thread.Sleep.

...