#c# #.net-core #asp.net-core-3.0
#c# #.net-ядро #asp.net-core-3.0
Вопрос:
Я пытаюсь получить асинхронные данные из HttpClient и добавить эти данные как одноэлементные в ConfigureServices в Startup.cs
public static class SolDataFill
{
static HttpClient Client;
static SolDataFill()
{
Client = new HttpClient();
}
public static async Task<SolData> GetData(AppSettings option)
{
var ulr = string.Format(option.MarsWheaterURL, option.DemoKey);
var httpResponse = await Client.GetAsync(ulr);
var stringResponse = await httpResponse.Content.ReadAsStringAsync();
var wheather = JsonConvert.DeserializeObject<SolData>(stringResponse);
return wheather;
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration);
var settings = Configuration.GetSection("NasaHttp") as AppSettings;
var sData = await SolDataFill.GetData(settings);
services.AddSingleton<SolData>(sData);
}
Возникает ошибка: можно использовать await только с async. Как добавить данные из асинхронного метода в singleton?
Комментарии:
1. Вы пробовали
var sData = SolDataFill.GetData(settings).Resu<
?2. Вы можете просто запустить этот метод синхронно, используя
GetAwaiter().GetResult()
Ответ №1:
Возможно, вам следует подумать о том, чтобы переработать ваш SolDataFill
, чтобы в конечном итоге стать сервисом данных, вместо того, чтобы добавлять все в контейнер DI.
Тогда все, кому нужны данные, могут запросить их. (Вот почему я добавил сюда кэш, чтобы не всегда выполнять запрос)
public class SolDataFill
{
private readonly HttpClient _client;
private readonly AppSettings _appSettings;
private readonly ILogger _logger;
private static SolData cache;
public SolDataFill(HttpClient client, AppSettings options, ILogger<SolDataFill> logger)
{
_client = client;
_appSettings = options;
_logger = logger;
}
public async Task<SolData> GetDataAsync()
{
if(cache == null)
{
var ulr = string.Format(_appSettings.MarsWheaterURL, _appSettings.DemoKey);
_logger.LogInformation(ulr);
var httpResponse = await _client.GetAsync(ulr);
if(httpResponse.IsSuccessStatusCode)
{
_logger.LogInformation("{0}", httpResponse.StatusCode);
var stringResponse = await httpResponse.Content.ReadAsStringAsync();
cache = JsonConvert.DeserializeObject<SolData>(stringResponse);
return cache;
}
else
{
_logger.LogInformation("{0}", httpResponse.StatusCode);
}
}
return cache;
}
}
Полный пример можно найти здесь
Как написано в комментариях к вашему вопросу, очень просто запустить асинхронный метод синхронно просто GetAwaiter().GetResult()
. Но, по моему мнению, каждый раз, когда я вижу этот код, я лично думаю, что есть скрытый запах кода, который можно переработать.