NCrunch v5.12 is now available. This release focuses entirely on stability and performance fixes, with a few of these deserving of note.
Xunit 3 1.1.0 Compatibility Fix
Version 1.1.0 of Xunit was released to Nuget about two weeks ago, including a change that checks to ensure that the Xunit test project is compiled as an executable with AppHost options enabled.
Under NCrunch v5.11, this check will fail every time, because NCrunch forces the UseAppHost build property to 'false', since the app host normally isn't required by NCrunch and there are a few downstream problems that can sometimes appear from having it enabled (mostly impacting synchronisation with grid nodes).
The check makes sense in the context of Xunit v3, as this version of Xunit relies on the test project itself being invokable as an EXE - an important change in Xunit as the test framework can then rely on the platform building the test environment.
However, NCrunch uses its own hosting infrastructure that is independent of this, so the app host isn't needed. NCrunch v5.12 thus disables the check and everything should work as normal.
File Synchronisation Changes
NCrunch relies heavily on FileSystemWatcher instances to keep track of files that change in the foreground solution, so that the contents of these files can then be synchronised with the engine. This is important because not all files are open in the IDE at a given point in time, and we still need to be able to push their contents into workspaces (perhaps even uploading to remote grid nodes) to keep everything in alignment. The previous approach for this has been to use a single FileSystemWatcher per project, with its target directory being set to the point of the lowest file in the directory structure being used by the project.
The cost of this can be significant in solutions with hundreds of projects making use of files several levels above their project directory, as it can cause a situation where we have several hundred watchers all assessing file system updates for the entire solution tree. When a large number of updates happen on disk, the cost of tracking everything quickly becomes overwhelming. The nature of this cost also has a heavy impact, as the FileSystemWatcher internally relies on I/O completion ports that are tied into the operating system with strict resource limitations. When a large number of updates are issued, these ports block up and actually start slowing down operations on the file system itself.
There have also been problems in the past related to directory locks being held by watchers, which can be annoying when making structural changes to a solution with NCrunch enabled.
So, under NCrunch v5.12, this approach has been revised. The watching of solution paths is now managed centrally to exclude redundant watchers. So in a situation where 100 projects all watching for changes at the base solution path, we will now have just one FileSystemWatcher that broadcasts updates internally.
In practice, this resolves the issue with I/O completion ports being jammed up and removes the overhead of O/S resources being overutilised. However, this does move the performance issue into the NCrunch engine itself, where it may (at times) take the engine a while to catch up if there are a massive number of operations on the file system in a short period of time.
I'm hopeful no further optimisation will be needed here, but I'm open to feedback on whether people are still having problems with NCrunch when moving large numbers of files inside their solution (i.e. on foreground builds that copy tens of thousands of files).
Console Support for Dotnet Build
It's now theoretically possible to use the NCrunch console tool without Visual Studio installed on the machine, using the .NET SDK for building projects instead.
Previously, when running the console tool with VS, you'd use something like the command line: ncrunch.exe /VS 2022
Now, it's possible to use: ncrunch.exe /VS dotnet
When this is specified, NCrunch will attempt to use installed versions of dotnet instead of VS. If you need to specify a version of the SDK to use, you can make use of the BuildSdk configuration setting, for example: ncrunch.exe /VS dotnet -BuildSdk 9.0.200
Note that some MS toolsets may still have dependencies on Visual Studio, so it's possible some solutions may still require VS to be installed on the machine.
Jetbrains Rider Fixes
v5.12 contains a disproportionate number of fixes for NCrunch under Rider. With Rider integration still being very new, there's naturally a lot of issues in this area still being worked through. I'm hopeful around getting Rider support out of Beta sometime in the next few months. Using Rider under v5.12 is feeling quite stable now and I'm personally finding issues much less often than before.