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 是否是创建延迟的正确方法(计时器不允许增加等待时间),如果是,我应该如何调用该方法来获取返回值?
您应该使用与实际操作相同的延迟样式。如果您SqlCommand是异步执行的,则使用Task.Delay延迟。如果你的SqlCommand是同步执行的,那么使用Thread.Sleep延迟。
听起来您仍然需要SqlCommand同步执行(至少现在),所以您应该使用Thread.Sleep. 最终,您可以使它们都异步(同时),但这听起来像是另一天的工作。
以某种方式Task.Delay替代. Thread.Sleep这Task.Delay只是.Thread.Sleep