gpt4 book ai didi

c# - 记录 ASP.NET Core 中的配置更改

转载 作者:行者123 更新时间:2023-12-04 15:55:06 25 4
gpt4 key购买 nike

我想在配置更改时记录。

I do thisProgram.csStartup.cs 中:

ChangeToken.OnChange(
() => configuration.GetReloadToken(),
state => logger.Information("Configuration reloaded"),
(object)null
);

但是我得到双重变化报告,所以它需要去抖动。 The advice is to do this :

ChangeToken.OnChange(
() => configuration.GetReloadToken(),
state => { Thread.Sleep(2000); logger.Information("Configuration reloaded"); },
(object)null
);

我在这里使用 2000 因为我不确定什么是合理的值。

我发现有时我仍然会收到多个变化检测,间隔为 2000 毫秒。所以去抖对我不起作用,只会导致报告更改之间的延迟。如果我设置一个高值,那么我只会得到一份报告,但这并不理想(并且掩盖了问题)。

所以我想知道:

  • 这真的是去抖动,还是只是对报告的变化进行排队?
  • 我使用了从 1000 到 5000 的值来取得不同程度的成功。其他人在用什么?
  • 是否向服务器的主线程发出 sleep ?我希望不会!

最佳答案

讨论的多重变更检测问题 here (以及多个 repo 中的至少十几个其他问题)是他们拒绝使用内置机制解决的问题。

MS 文档使用 file hashing方法,但我认为去抖更好。

我的解决方案使用异步(避免可能意外炸毁某些东西的异步同步)和 hosted service消除变化检测。

Debouncer.cs:

public sealed class Debouncer : IDisposable {

public Debouncer(TimeSpan? delay) => _delay = delay ?? TimeSpan.FromSeconds(2);

private readonly TimeSpan _delay;
private CancellationTokenSource? previousCancellationToken = null;

public async Task Debounce(Action action) {
_ = action ?? throw new ArgumentNullException(nameof(action));
Cancel();
previousCancellationToken = new CancellationTokenSource();
try {
await Task.Delay(_delay, previousCancellationToken.Token);
await Task.Run(action, previousCancellationToken.Token);
}
catch (TaskCanceledException) { } // can swallow exception as nothing more to do if task cancelled
}

public void Cancel() {
if (previousCancellationToken != null) {
previousCancellationToken.Cancel();
previousCancellationToken.Dispose();
}
}

public void Dispose() => Cancel();

}

ConfigWatcher.cs:

public sealed class ConfigWatcher : IHostedService, IDisposable {

public ConfigWatcher(IServiceScopeFactory scopeFactory, ILogger<ConfigWatcher> logger) {
_scopeFactory = scopeFactory;
_logger = logger;
}

private readonly IServiceScopeFactory _scopeFactory;
private readonly ILogger<ConfigWatcher> _logger;

private readonly Debouncer _debouncer = new(TimeSpan.FromSeconds(2));

private void OnConfigurationReloaded() {
_logger.LogInformation("Configuration reloaded");
// ... can do more stuff here, e.g. validate config
}

public Task StartAsync(CancellationToken cancellationToken) {
ChangeToken.OnChange(
() => { // resolve config from scope rather than ctor injection, in case it changes (this hosted service is a singleton)
using var scope = _scopeFactory.CreateScope();
var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
return configuration.GetReloadToken();
},
async () => await _debouncer.Debounce(OnConfigurationReloaded)
);
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;

public void Dispose() => _debouncer.Dispose();

}

Startup.cs:

services.AddHostedService<ConfigWatcher>();        // registered as singleton

关于c# - 记录 ASP.NET Core 中的配置更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52053948/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com