Watch and Hot Reload
|
This section documents MSBuild 18.9, the .NET SDK 10.0.402 (with its This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The C# Reference bibliography lists the reference material consulted while preparing these pages. |
dotnet watch runs a command — dotnet run by default, or test, build and others named after it — and runs it
again whenever a watched file changes. With hot reload, many code edits are applied to the running process
instead, so the application keeps its state. This page exercises both with .NET SDK 10.0.402 on a small console
program.
A hot reload and a rude edit
The program prints a counter every second:
for (var i = 0; ; i++)
{
Console.WriteLine(Message(i));
Thread.Sleep(1000);
}
static string Message(int i) => $"tick {i}";
dotnet watch --non-interactive was started, and after a few seconds two edits were made: first the message text,
then the parameter type of Message (int to long). The watcher’s output, without the program’s own lines:
dotnet watch ๐ฅ Hot reload enabled. For a list of supported edits, see https://aka.ms/dotnet/hot-reload.
dotnet watch ๐ก Press Ctrl+R to restart.
W -> ~/watch/bin/Debug/net10.0/W.dll
Build succeeded.
dotnet watch โ Loading projects ...
dotnet watch โ Loaded 1 project(s) in 0.4s.
dotnet watch โ Waiting for changes
dotnet watch โ File updated: ./Program.cs
dotnet watch ๐ฅ C# and Razor changes applied in 1204ms.
dotnet watch โ File updated: ./Program.cs
dotnet watch ๐ฅ Restart is needed to apply the changes.
dotnet watch โ [W (net10.0)] Exited
W -> ~/watch/bin/Debug/net10.0/W.dll
Build succeeded.
dotnet watch โ Waiting for changes
And the program’s output around the two edits:
tick 9
tick 10
balance check 11
balance check 12
โฆ
balance check 17
balance check 0
balance check 1
-
The first edit was hot-reloaded. The new text appeared at
11: the loop and its counter kept running, and only the method body was replaced. -
The second edit was a rude edit. Changing a method signature cannot be applied to running code, so the process was stopped, rebuilt and started again — the counter restarted at
0. In an interactive terminaldotnet watchasks first: "Do you want to restart your app - Yes (y) / No (n) / Always (a) / Never (v)?";--non-interactiverestarts without asking.
Which edits hot reload supports depends on the runtime and the project type (adding methods and fields, changing
method bodies and lambdas are supported; changing signatures, base types or generic type definitions generally are
not). --no-hot-reload turns it off and restores the plain re-run behaviour; Ctrl+R restarts on demand.
Source: dotnet watch: Hot reload, Rude edits.
What is watched
dotnet watch watches the Watch item group, which by default holds all Compile and EmbeddedResource items
(**/*.cs, the project file, **/*.resx, plus wwwroot/** in web projects), across the whole graph of project
references. --list prints it without starting anything:
dotnet watch --list
~/watch/Program.cs
~/watch/W.csproj
A data file read by the program is not in the list. Adding it — and opting a file in or out explicitly — is done with items:
<ItemGroup>
<Watch Include="accounts.txt" />
<Compile Update="Program.cs" Watch="true" />
</ItemGroup>
~/watch/accounts.txt
~/watch/Program.cs
~/watch/W.csproj
Watch="false" on a Compile, EmbeddedResource or ProjectReference item excludes it, and from .NET 10 the
DefaultItemExcludes property excludes whole folders or patterns ($(DefaultItemExcludes);**/App_Data/**;**/*.log).
Source: dotnet watch: Files watched by default, Watch additional files, Ignore specified files and folders.
A log file that wakes the watcher
The first run of the experiment above redirected the watcher’s output to watch.log inside the project folder. Every
write to the log was reported as a change:
dotnet watch โ File updated: ./watch.log
dotnet watch โ No managed code changes to apply.
dotnet watch โ File updated: ./watch.log
dotnet watch โ No managed code changes to apply.
— repeated for every line the program printed, although --list does not show watch.log. Nothing was rebuilt, but
the output was flooded. Keep logs, databases and other files the application writes outside the project folder, or
exclude them with DefaultItemExcludes.
Other commands
dotnet watch test re-runs the tests on every change, and dotnet watch build only rebuilds — both without hot
reload. dotnet watch --file app.cs (or dotnet watch app.cs) watches a file-based app
(Run and File-Based Apps).
Common mistakes
-
Expecting a rude edit to apply — the app restarts and loses its state.
-
Writing files into the project folder at run time — the watcher reacts to every write.
-
Data files that should trigger a restart but are not
Watchitems — add them. -
Using
dotnet watchin CI — it never exits; it is an inner-loop tool.