Skip to content

Conversation

@RikkiGibson
Copy link
Member

@RikkiGibson RikkiGibson commented Sep 17, 2025

Closes #80242

What was happening was, a restore would modify the assets file and cause our watcher to get notified, even though the actual content didn't change. The design time build would notice that assets were still missing and kick off another restore, which would fail again, but generate the file watcher event, in a cycle.

The change is to hash the assets file content when we get a change notification for it, and compare it with the hash from the previous notification, to make sure a meaningful content change has occurred, before kicking off a design time build based on it.

With this change we no longer get a restore loop for a package directive like #:package Newtonsoft.Json:13.0.4.

@RikkiGibson RikkiGibson requested a review from a team as a code owner September 17, 2025 23:00
Comment on lines 109 to 110
using var assetsFileStream = File.OpenRead(filePath);
var sourceText = SourceText.From(assetsFileStream);
Copy link
Member Author

@RikkiGibson RikkiGibson Sep 17, 2025

Choose a reason for hiding this comment

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

Is this the right way to do read the assets file in this context? Is there some other pattern that should be used instead?

Copy link
Member

Choose a reason for hiding this comment

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

It should be wrapped in an IOUtilities.PerformIO() to deal with the case of this throwing some sort of I/O exception.

Copy link
Member Author

@RikkiGibson RikkiGibson Sep 18, 2025

Choose a reason for hiding this comment

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

I am going to make an assumption that we don't need to handle a scenario where we are notified the assets file changed, and, the file was actually deleted from disk.

I guess I am also making an assumption that if we got an IOException when reading the file for some other reason, that there isn't a need to start a design time build.

When I use this helper, is there any need to log or anything in the case an IO exception is thrown?

@RikkiGibson
Copy link
Member Author

@dibarbet @jasonmalinowski for review

Comment on lines 109 to 110
using var assetsFileStream = File.OpenRead(filePath);
var sourceText = SourceText.From(assetsFileStream);
Copy link
Member

Choose a reason for hiding this comment

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

It should be wrapped in an IOUtilities.PerformIO() to deal with the case of this throwing some sort of I/O exception.

NeedsReload?.Invoke(this, EventArgs.Empty);
}

private void AssetsFileChangeContext_FileChanged(object? sender, string filePath)
Copy link
Member

Choose a reason for hiding this comment

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

There's a theoretical race here where the file path being passed might be to an assets file that isn't actually being watched anymore. Not sure that matters in any useful way; just deal with the IO exceptions in case it's gone.

@RikkiGibson RikkiGibson merged commit 9eb6d53 into dotnet:main Sep 18, 2025
25 checks passed
@RikkiGibson RikkiGibson deleted the fix-80242 branch September 18, 2025 18:32
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Sep 18, 2025
333fred added a commit that referenced this pull request Sep 18, 2025
* upstream/main: (206 commits)
  Remove bogus xlf tag (#80357)
  Fix missing type argument checks
  Add tests
  Use dotnet run file for generating compiler code (#80248)
  Only restore based on assets file changes if the actual content changed (#80341)
  make expressionbody analyzer use semanticspananalysis (#80339)
  [EnC] Use ignoreAssemblyKey: false to resolve symbol keys (#80342)
  Properly populate ExportedType metadata table in presence of extension block. (#80311)
  Propagate `params` to lambdas and local functions (#79880)
  Change 17.15 to VS 2026 preview. (#80325)
  Improve virtualproject support for older .NET SDKs (#80324)
  Update dependencies from https://github.com/dotnet/dotnet build 283666 (#80344)
  Update dependencies from https://github.com/dotnet/arcade build 20250917.6 (#80343)
  Simplifying
  Fix tests
  Fix tests
  Fix introduce variable placement in top level statements
  move to immutable types in signature help
  move to immutable types in signature help
  Fix check
  ...
333fred added a commit to 333fred/roslyn that referenced this pull request Sep 18, 2025
* upstream/main: (31 commits)
  Remove bogus xlf tag (dotnet#80357)
  Fix missing type argument checks
  Add tests
  Use dotnet run file for generating compiler code (dotnet#80248)
  Only restore based on assets file changes if the actual content changed (dotnet#80341)
  make expressionbody analyzer use semanticspananalysis (dotnet#80339)
  [EnC] Use ignoreAssemblyKey: false to resolve symbol keys (dotnet#80342)
  Properly populate ExportedType metadata table in presence of extension block. (dotnet#80311)
  Propagate `params` to lambdas and local functions (dotnet#79880)
  Change 17.15 to VS 2026 preview. (dotnet#80325)
  Improve virtualproject support for older .NET SDKs (dotnet#80324)
  Update dependencies from https://github.com/dotnet/dotnet build 283666 (dotnet#80344)
  Update dependencies from https://github.com/dotnet/arcade build 20250917.6 (dotnet#80343)
  Simplifying
  Fix tests
  Fix tests
  Fix introduce variable placement in top level statements
  move to immutable types in signature help
  move to immutable types in signature help
  Fix check
  ...
@akhera99 akhera99 modified the milestones: Next, 18.0 P1, 18.0 P2 Sep 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Restore loop in file-based programs

3 participants