如何在net.core 3.0中的Startup.cs中从单例中的异步方法添加数据?

问题描述

我正在尝试从HttpClient获取异步数据,并将此数据作为单例添加到Startup.cs的ConfigureServices中。

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一起使用。如何从异步方法向单例添加数据?

解决方法

也许您应该考虑对SolDataFill进行重新处理以最终成为DataService,而不是将所有内容添加到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;
    }
}

Full example can be found here

就像在问题注释中所写,仅通过GetAwaiter().GetResult()来同步运行异步方法非常简单。但是每次我看到此代码时,我个人都认为隐藏了代码气味,可以重构。