.NET 7 WPF中IOptionsMonitor首次变更触发两次OnChange回调问题
问题描述
环境与配置
基于.NET 7的WPF应用,引入的NuGet包:
- CommunityToolkit.Mvvm 8.0.0
- Microsoft.Extensions.Configuration 7.0.0
- Microsoft.Extensions.Configuration.Json 7.0.0
- Microsoft.Extensions.Options.ConfigurationExtensions 7.0.0
配置代码(App.xaml.cs)
var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appSettings.json", optional: false, reloadOnChange: true) .Build(); _serviceProvider = new ServiceCollection() .Configure<AppSettings>(configuration.GetSection(nameof(AppSettings))) .BuildServiceProvider();
appSettings.json内容
{ "AppSettings": { "IsUpdating": false } }
AppSettings类定义
public partial class AppSettings : ObservableObject { [ObservableProperty] private bool isUpdating; }
ViewModel中的监听代码
public partial class ViewModel : ObservableObject { [ObservableProperty] private AppSettings settings; public ViewModel(IOptionsMonitor<AppSettings> appSettings) { appSettings.OnChange<AppSettings>(SettingsChanged); settings = appSettings.CurrentValue; } private void SettingsChanged(AppSettings appSettings) { Settings.IsUpdating = appSettings.IsUpdating; } }
异常现象
在SettingsChanged方法设置断点后:
- 修改
appSettings.json中的IsUpdating值,首次修改会连续触发两次断点,后续修改仅触发一次;重启应用后该现象100%重现。 - 仅保存配置文件未做任何修改时,也会触发
SettingsChanged回调。
疑问
- 首次检测到配置变更时发生了什么,导致后续变更不会出现该情况?
- 为何仅保存配置文件未做修改时,也会触发
SettingsChanged回调?
问题解答
1. 首次修改触发两次回调的原因
这是.NET配置系统文件变更检测的初始逻辑导致:
- 首次修改保存文件时,文件系统的变更通知被捕获,配置系统会重新加载JSON文件,触发第一次回调。
- 由于首次加载后配置系统内部存在缓存初始化或校验步骤,会额外触发一次配置同步动作,导致第二次回调。
- 后续修改时,配置系统的缓存已处于稳定状态,不会再执行额外的同步步骤,因此仅触发一次回调。
2. 未修改保存也触发回调的原因
配置系统的reloadOnChange是通过监听文件的修改时间戳来判断是否需要重新加载的。即使文件内容未变,执行保存操作时操作系统会更新文件的LastWriteTime,配置系统检测到时间戳变化后,会重新加载文件并触发OnChange回调。
如果要避免无内容变更时触发逻辑,可以在SettingsChanged方法中自行对比新旧配置的实际值,仅当值确实变化时再执行后续操作。
内容的提问来源于stack exchange,提问作者537mfb
相关产品推荐
相关产品推荐

