Ubuntu环境下ChangeToken.OnChange失效?.NET配置监听问题
.NET配置文件变更监听单元测试跨环境失败问题
问题背景
我编写了一个供多项目使用的类库,封装了基于配置文件变更的更新逻辑。单元测试通过覆写被监听的JSON文件验证该逻辑,本地测试100%通过,但构建服务器上通过率不足50%——3个用例中2个从未通过,1个偶尔通过。
该项目原本基于.NET 7,升级至.NET 8后问题仍存在。我剥离类库代码编写了极简复现示例(见下文),本地每次运行均通过,但构建服务器上最终断言始终失败。
环境细节
- 测试框架:xUnit 2.8.1
- 开发机:macOS 14.5(也在Windows 10上测试过)
- 构建服务器:基于微软官方.NET SDK镜像的Docker容器(Ubuntu系统)
已尝试的无效调试手段
- 将文件扩展名改为
.json - 使用流而非
File.WriteAllText()更新文件 - 更新文件后调用
File.SetLastWriteTimeUtc(configFilePath, DateTime.UtcNow) - 添加并延长各处延迟
- 传入非null对象作为state(实际代码已这么做)
- 在Lambda内调用
config.GetReloadToken()而非直接传递方法引用
我不愿轻易归咎于框架,但类库最终将在Linux容器中运行,必须明确问题根源。曾找到一个GitHub Issue描述相似行为,但已4年未更新。请问这是代码问题还是运行时Bug?
复现代码
[Fact] public void BasicTest() { var configFilePath = Path.GetTempFileName(); File.WriteAllText(configFilePath, "{ \"MyValue\": 5 }"); var config = new ConfigurationBuilder() .AddJsonFile(configFilePath, optional: false, reloadOnChange: true) .Build(); var invokeWasCalled = false; _ = ChangeToken.OnChange<object>( config.GetReloadToken, _ => invokeWasCalled = true, null!); File.WriteAllText(configFilePath, "{ \"MyValue\": 15 }"); Thread.Sleep(TimeSpan.FromMilliseconds(500)); invokeWasCalled.Should().BeTrue(); }
内容的提问来源于stack exchange,提问作者Dov
相关产品推荐
相关产品推荐

