用 Task.Delay 替换 Thread.Sleep

Tim*_*Tim 1 c# asynchronous task async-await

我正在重构代码,该代码使用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;
    }
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是async要求调用方法为async,等等。虽然最终重构为完全异步,但这远远超出了当前的重构范围。

我遇到的问题是如何从同步代码调用该方法并获取结果。使用

retryCount = PrepareForRetry(retryCount, command, timeout).Result;
Run Code Online (Sandbox Code Playgroud)

由于 UI 线程正在调用该方法,因此会造成死锁。我发现我可以通过将我的更改Task.Delay

await Task.Delay(SleepTime).ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)

但我不完全明白这是做什么的。我也尝试过使用调用该方法

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

但这有错误“'int'不包含'GetAwaiter'的定义”,并且我无法找出如何继续获得结果。使用 Task.Delay 是否是创建延迟的正确方法(计时器不允许增加等待时间),如果是,我应该如何调用该方法来获取返回值?

Ste*_*ary 5

您应该使用与实际操作相同的延迟样式。如果您SqlCommand是异步执行的,则使用Task.Delay延迟。如果你的SqlCommand是同步执行的,那么使用Thread.Sleep延迟。

听起来您仍然需要SqlCommand同步执行(至少现在),所以您应该使用Thread.Sleep. 最终,您可以使它们都异步(同时),但这听起来像是另一天的工作。

某种方式Task.Delay替代.Thread.SleepTask.Delay只是.Thread.Sleep