You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:15:10