debugcsharpMinor
Retry loop for asynchronous HTTP requests
Viewed 0 times
asynchronousloophttpforrequestsretry
Problem
I've got a method that needs to PUT data to a web API. Sometimes the connection fails, so I needed a way to do retries, but if the retries fail, I still need to capture the exception and re-throw it.
I've got something that I "believe" is working, but I've got a stupid throw at the end. Is there a better, more concise way to do this when working with async tasks?
I've got something that I "believe" is working, but I've got a stupid throw at the end. Is there a better, more concise way to do this when working with async tasks?
private const int TotalNumberOfAttempts = 10;
public static async Task PutWithRetriesAsync(string url,
HttpContent content,
AuthenticationHeaderValue authenticationHeaderValue,
MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue)
{
var numberOfAttempts = 0;
ExceptionDispatchInfo capturedException;
do
{
try
{
return await PutAsync(url, content, authenticationHeaderValue, mediaTypeWithQualityHeaderValue);
}
catch (AggregateException ex)
{
capturedException = ExceptionDispatchInfo.Capture(ex);
numberOfAttempts++;
}
} while (numberOfAttempts < TotalNumberOfAttempts);
if (capturedException != null)
{
capturedException.Throw();
}
throw new Exception("That will never be thrown");
}Solution
I would rewrite your code into a
This way, you don't need
I also changed
while (true) loop, that can only be exited using the return in your try or using a throw; inside a condition in your catch:while (true)
{
try
{
return await PutAsync(url, content, authenticationHeaderValue, mediaTypeWithQualityHeaderValue);
}
catch
{
numberOfAttempts++;
if (numberOfAttempts >= TotalNumberOfAttempts)
throw;
}
}This way, you don't need
ExceptionDispatchInfo or the useless (but required by the compiler) throw at the end.I also changed
catch (AggregateException ex) to catch all exceptions, because await usually doesn't throw AggregateException (unlike task.Wait() or task.Result).Code Snippets
while (true)
{
try
{
return await PutAsync(url, content, authenticationHeaderValue, mediaTypeWithQualityHeaderValue);
}
catch
{
numberOfAttempts++;
if (numberOfAttempts >= TotalNumberOfAttempts)
throw;
}
}Context
StackExchange Code Review Q#59829, answer score: 3
Revisions (0)
No revisions yet.