【问题标题】:Sharing configuration values between different BackgroundServices .NET Core 2.1在不同的 BackgroundServices .NET Core 2.1 之间共享配置值
【发布时间】:2020-11-06 20:44:45
【问题描述】:

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

我该怎么做?我可以使用.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);
}

【问题讨论】:

  • 在这些后台服务之间共享内存还不够吗?就像 Redis 内存存储一样,您可以在其中存储和检索内存数据。
  • @Bruno 我正在寻找可以在 .NET 已经提供的这些后台服务之间共享的东西。
  • 那么你应该考虑进程间通信,如下所述:stackoverflow.com/questions/528652/… 但我个人会创建一个 webapi 并将其用作通信“层”将是实现你想要的最简单的方法.

标签: c# .net-core configuration asp.net-core-2.1


【解决方案1】:

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

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

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

【讨论】:

  • 这听起来可以解决我的问题,你的AsyncCache 详细信息是什么?
  • My AsyncCache is in a Gist。它没有经过全面测试,可能不完整且不正确。
猜你喜欢
  • 2019-07-05
  • 2019-06-07
  • 2023-03-08
  • 1970-01-01
  • 2019-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
相关资源
最近更新 更多