首页 > 解决方案 > 在不同的 BackgroundServices .NET Core 2.1 之间共享配置值

问题描述

我有一个 .NET Core 控制台应用程序,我在 .NET Core 2.1 中作为 Windows 服务运行。我最终将拥有多个BackgroundService最终会进行网络通话的工人阶级。其中一些 Web 调用依赖于从它们自己的AuthTokenWorker BackgroundService. 我计划将这些代币保存在一个工人阶级中,并与其他工人阶级分享价值。

我怎么做?我可以使用.ConfigureAppConfiguration和使用内存中的集合吗?如果我从一个 Worker 更新该配置中的令牌,其他通过 DI 使用相同配置的人会收到更新的值吗?做那个方法线程安全吗?

过去,我使用了一个泛型static Configuration类,它ConcurrentDictionary只是从不同的类中保存/获取值,但我是 .NET Core 的新手,想知道实现此目的的适当方法。

例如。

Program.cs

static void Main(string[] args)
{
    CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices((hostBuilderContext, serviceCollection) =>
        {
            serviceCollection.AddHttpClient<SClient>();
            serviceCollection.AddHttpClient<DClient>();
            serviceCollection.AddHostedService<SWorker>();
            serviceCollection.AddHostedService<DWorker>();
        }).UseWindowsService();

}

SWorker.cs

我想使用公共财产DWorker.cs

public SClient(ILogger<STSTokenClient> logger, HttpClient client)
{
    _logger = logger;
    _client = client;
}

public SToken Token { get; internal set;}

由于我需要一个对象来引用该属性,我可以通过构造函数注入它吗?

DWorker.cs

public DWorker(ILogger<DWorker> logger, SWorker sWorker,
    DClient dClient)
{
    _logger = logger;
    _sWorker = sWorker;
    _dClient = dClient;
}


protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    ...
    var token = await _dClient.FetchTokenAsync(_sWorker.Token);
}

标签: c#.net-coreconfigurationasp.net-core-2.1

解决方案


我计划将这些代币保存在一个工人阶级中,并与其他工人阶级分享价值。

变异配置可能有效,但这是解决此问题的一种奇怪方法。更自然的方法是使用类似于IMemoryCache众所周知的键的东西。

请注意,forGetOrCreateGetOrCreateAsync扩展方法IMemoryCache不是原子的。如果您想要一个异步兼容的“刷新此令牌,但如果它已经被刷新,则共享该刷新请求”类型的操作,那么您需要自己构建它。如果你需要,我有一个可以提供帮助的。AsyncCache


推荐阅读