I am refactoring code that uses Thread.Sleep
with an increasing time limit to retry SQL queries when there were errors. The common replacement for Thread.Sleep
for blocking seems to be await Task.Delay
, which required changing the method to async
. The method now looks like this (additional error checking removed for brevity):
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;
}
The problem that I'm having is that async
requires the calling method to be async
, and so forth. Although eventually refactoring to fully asynchronous, this is well beyond the current refactor scope.
The issue I'm having is how to call the method from synchronous code and getting the result. Using
retryCount = PrepareForRetry(retryCount, command, timeout).Result;
creates a deadlock, since a UI thread is calling the method. I've seen that I can resolve this by changing my Task.Delay
to
await Task.Delay(SleepTime).ConfigureAwait(false);
but I don't fully understand what this does. I've also tried calling the method using
retryCount = Task.Run(async () => { await PrepareForRetry(retryCount, command, timeout).Result; });
but this has the error " 'int' does not contain a definition for 'GetAwaiter' ", and I've not been able to find out how I can proceed to get the result. Is using Task.Delay the correct way of creating the delay (a timer doesn't allow for the increase in wait times), and if so, how should I call the method to get the return value?