Ваш код выглядит дублированным для меня.Вместо того, чтобы делать 3 разные функции, у вас должна быть одна с аргументами:
public async Task<string> GetStringFromAPIAsync( string resource )
{
// check input
if( string.IsNullOrWhitespace(resource) ) throw new ArgumentException(nameof(resource));
using (HttpResponseMessage result = await _httpClient.GetAsync(resource))
using (HttpContent content = result.Content)
{
result.EnsureSuccessStatusCode();
return await content.ReadAsStringAsync();
// Issue in your code: 'data' was out of scope for the return.
// string data = await content.ReadAsStringAsync();
}
// return data; <- "data" is not visible here!
}
Имейте в виду, что я избавился от всей обработки исключений здесь, так как из моего POV это должно делать вызывающая сторона, котораятакже дает вам больше гибкости.
Например: вы можете написать другую функцию для повторения, например:
public async Task<string> GetStringFromAPIWithRetryAsync(string resource, int maxRetry)
{
// limit retry to 1 .. 100
for( int retry = Math.Min(Math.Max(1,maxRetry),100); retry > 0 ; retry--){
try{
return await GetStringFromAPIAsync( resource );
}
catch(Exception ex){ // Actually, you'd only catch exceptions where a retry makes sense.
if( retry > 0 ){
Log.Warn("Attempt to get string from {0} failed! Reason: {1}", resource, ex.Message);
}else{
throw;
}
}
}
}
Если вам просто нужно значение по умолчанию в случае ошибки, вы можете сделать это:
public async Task<string> GetStringFromAPIOrDefaultAsync(string resource, string defaultValue)
{
string returnValue = defaultValue;
try{
returnValue = await GetStringFromAPIAsync( resource );
}
catch(Exception){
Log.Warn("Attempt to get string from {0} failed! Reason: {1}", resource, ex.Message);
}
return returnValue;
}
}