Reputation: 2911
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?
Upvotes: 1
Views: 1252
Reputation: 456322
You should use the same style for delays as you do for the actual operation. If your SqlCommand
is executed asynchronously, then use Task.Delay
for delays. If your SqlCommand
is executed synchronously, then use Thread.Sleep
for delays.
It sounds like you still need your SqlCommand
to be executed synchronously (at least for now), so you should be using Thread.Sleep
. Eventually, you could make them both asynchronous (at the same time), but it sounds like that is work for another day.
It's not true that Task.Delay
is somehow a replacement for Thread.Sleep
. It's just that Task.Delay
is the asynchronous equivalent of Thread.Sleep
.
Upvotes: 5