我正在重构使用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;
创建死锁,因为UI线程正在调用该方法。我已经看到可以通过将Task.Delay
更改为
await Task.Delay(SleepTime).ConfigureAwait(false);
但是我不完全了解它的作用。我也尝试过使用
调用该方法retryCount = Task.Run(async () => { await PrepareForRetry(retryCount, command, timeout).Result; });
但是它有错误“'int'不包含'GetAwaiter'的定义”,并且我无法找出如何继续获取结果的方法。使用Task.Delay是创建延迟的正确方法(计时器不允许增加等待时间),如果是这样,我应该如何调用该方法以获取返回值?
答案 0 :(得分:3)
对于延迟,应该使用与实际操作相同的样式。如果您的SqlCommand
是异步执行的,请使用Task.Delay
进行延迟。如果您的SqlCommand
是同步执行的,请使用Thread.Sleep
进行延迟。
听起来您仍然需要SqlCommand
同步执行(至少现在是这样),所以您应该使用Thread.Sleep
。最终,您可以(同时)使它们都异步,但是听起来好像又要工作了一天。
Task.Delay
在某种程度上是Thread.Sleep
的替换,这是不是。只是Task.Delay
是Thread.Sleep
的异步等效。