Skip to content

Use async ChangeToken.OnChange overload in KeyPerFileConfigurationProvider#67732

Open
svick wants to merge 3 commits into
dotnet:mainfrom
svick:keyperfile-async-changetoken
Open

Use async ChangeToken.OnChange overload in KeyPerFileConfigurationProvider#67732
svick wants to merge 3 commits into
dotnet:mainfrom
svick:keyperfile-async-changetoken

Conversation

@svick

@svick svick commented Jul 10, 2026

Copy link
Copy Markdown
Member

Uses the new async (Func<Task>) overload of ChangeToken.OnChange (see dotnet/runtime#69099) in KeyPerFileConfigurationProvider.

The reload callback previously blocked the file-watcher callback thread for the whole reload delay via Thread.Sleep(Source.ReloadDelay) (default 250 ms). It now awaits Task.Delay(...) instead, so no thread is blocked while waiting out the debounce delay before reloading:

_changeTokenRegistration = ChangeToken.OnChange(
    () => Source.FileProvider.Watch("*"),
    async () =>
    {
        await Task.Delay(Source.ReloadDelay).ConfigureAwait(false);
        Load(reload: true);
    });

The same change for FileConfigurationProvider is at dotnet/runtime#130492.

Test changes

Two reload tests asserted the reloaded configuration synchronously immediately after triggering a change, which only worked because the old Thread.Sleep ran the reload inline on the change-notification thread. With the non-blocking async reload, the reload now completes on a thread-pool thread, so these tests now await the config reload token before asserting — matching the existing RaiseChangeEventWhenReloadOnChangeIsTrue test:

  • ReloadConfigWhenReloadOnChangeIsTrue
  • NoFilesReloadWhenAddedFiles

Note

This PR description was generated by GitHub Copilot.

…vider

Replace the blocking Thread.Sleep in the reload callback with an
awaited Task.Delay, using the async Func<Task> overload of
ChangeToken.OnChange added in dotnet/runtime#69099. This avoids
blocking the file-watcher callback thread for the reload delay.

Two reload tests that asserted synchronously after triggering a change
relied on the previous blocking behavior; they now await the config
reload token before asserting, matching the existing
RaiseChangeEventWhenReloadOnChangeIsTrue test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 059bf1b8-31e2-4608-a038-210880f90d06
@svick svick marked this pull request as ready for review July 13, 2026 12:36
Copilot AI review requested due to automatic review settings July 13, 2026 12:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the KeyPerFile configuration provider to use the async (Func<Task>) ChangeToken.OnChange overload so reload debouncing (ReloadDelay) no longer blocks the file-watcher callback thread, and adjusts related tests to await reload completion.

Changes:

  • Switch KeyPerFileConfigurationProvider reload callback from Thread.Sleep to await Task.Delay(...) before reloading.
  • Add a try/catch around Load(reload: true) in the change callback to avoid exceptions escaping the async callback.
  • Update reload-related tests to be async, await the reload token, and apply timeouts.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/Configuration.KeyPerFile/src/KeyPerFileConfigurationProvider.cs Uses async OnChange callback and Task.Delay for non-blocking debounce before reload.
src/Configuration.KeyPerFile/test/KeyPerFileTests.cs Converts relevant tests to async and waits for the reload token before asserting.

Comment thread src/Configuration.KeyPerFile/test/KeyPerFileTests.cs Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants