Msbuild: Failed build leaves MSBuild processes lying around

Created on 16 Feb 2017  路  14Comments  路  Source: dotnet/msbuild

I have a (closed-source) .NET Core project that uses some custom MSBuild tasks. The tasks are cross-built for both netcoreapp1.1 and .NET Framework 4.6, so that they will work properly in both dotnet build and Visual Studio.

However, when I run the build from within VS and it fails, three or four MSBuild.exe processes remain lying around, holding the DLL containing the tasks open, requiring me to taskkill them before I can replace the DLL with a version containing fixes for debugging. dotnet build does not appear to do this. I am using VS 2017 RC4 build 26206. As far as I can recall, this did not occur on previous builds of VS2017.

Most helpful comment

This feature is called node reuse. You can turn it off on the command-line by running MSBuild.exe /nodeReuse:false (or just /nr:false). If you want it to not happen in Visual Studio you can set environment variable MSBUILDDISABLENODEREUSE=1. This features (for various reasons) is not supported in the .NET Core version of MSBuild so it will never happen.

That being said, the feature is there for performance. Your builds will be quite a bit slower with this turned off. It was added to avoid the overhead of process creation (with many projects and many cores it can be significant) and JIT.

I'm going to close this since it's by design. Hopefully this answers your question though? If you think there's really a behavior change between VS2015 and VS2017 feel free to re-open with repro steps. There should be no change.

All 14 comments

This feature is called node reuse. You can turn it off on the command-line by running MSBuild.exe /nodeReuse:false (or just /nr:false). If you want it to not happen in Visual Studio you can set environment variable MSBUILDDISABLENODEREUSE=1. This features (for various reasons) is not supported in the .NET Core version of MSBuild so it will never happen.

That being said, the feature is there for performance. Your builds will be quite a bit slower with this turned off. It was added to avoid the overhead of process creation (with many projects and many cores it can be significant) and JIT.

I'm going to close this since it's by design. Hopefully this answers your question though? If you think there's really a behavior change between VS2015 and VS2017 feel free to re-open with repro steps. There should be no change.

three or four MSBuild.exe processes remain lying around, holding the DLL containing the tasks open, requiring me to taskkill them

I am running into this at the moment with VS 15.2 (26430.16). In a small solution after debugging a WPF application a couple of times.

@AndyGerlicher are you aware of a recent issue in VS that might couse this? One thing that should be mentioned probably is I use https://github.com/Fody/PropertyChanged that hooks into the build process.

@mpseidel Have you figured out how to fix this problem?

I'm also using FodyPropertyChanged and VS2017.

@gabrielpra1 hey - I've set the environment variable

MSBUILDDISABLENODEREUSE = 1

That had solved the issue for me back then - haven't worked on that project for a while now.

https://github.com/Microsoft/msbuild/wiki/MSBuild-Tips-&-Tricks#msbuildexe-nrfalse

This is also happening to me, in any build, no matter if it succeeds or fails. Disable node reuse didn't help.
Any idea what else can I try?

I have the same Problem as @fedeazzato . The MSBuild.exe is still running after a build.


If running msbuild from command line with: /nodeReuse:false everything works as expected, but using

<Project TreatAsLocalProperty="NodeReuse" ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <MSBUILDDISABLENODEREUSE>True</MSBUILDDISABLENODEREUSE> or <MSBUILDDISABLENODEREUSE>1</MSBUILDDISABLENODEREUSE>
    <NodeReuse>False</NodeReuse>

and compiling from visualStudio the MSBuild.exe is still running afterwards!

@dojo90 Have you tried setting the MSBUILDDISABLENODEREUSE globally (Option 1 here)? That worked for me.

@AndyGerlicher I'm running into this in VS despite setting MSBUILDDISABLENODEREUSE=1 globally. Specifically, a UsingTask is unable to copy its AssemblyFile because the target is locked by a previous invocation of MSBuild.

I think it goes back to this old Q&A: Visual Studio 2008 locks custom MSBuild Task assemblies. The fundamental issue seems to be that there's no way to tell UsingTask to load the task in a disposable AppContext, so the assembly ends up being loaded by the AppContext that VS keeps around... or something like that. After banging on this for a couple days, I'm coming to the conclusion that there is no way to use custom MSBuild tasks in a VS project without resorting to weird hacks like launching them from an inline task.

@gabrielpra1 hey - I've set the environment variable

MSBUILDDISABLENODEREUSE = 1

That had solved the issue for me back then - haven't worked on that project for a while now.

https://github.com/Microsoft/msbuild/wiki/MSBuild-Tips-&-Tricks#msbuildexe-nrfalse

$env:MSBUILDDISABLENODEREUSE = 1
This worked great in a Powershell solution build script, thank you!
MSBuild processes are gone after the build script has completed now.

This feature is called node reuse. You can turn it off on the command-line by running MSBuild.exe /nodeReuse:false (or just /nr:false). If you want it to not happen in Visual Studio you can set environment variable MSBUILDDISABLENODEREUSE=1. This features (for various reasons) is not supported in the .NET Core version of MSBuild so it will never happen.

That being said, the feature is there for performance. Your builds will be quite a bit slower with this turned off. It was added to avoid the overhead of process creation (with many projects and many cores it can be significant) and JIT.

I'm going to close this since it's by design. Hopefully this answers your question though? If you think there's really a behavior change between VS2015 and VS2017 feel free to re-open with repro steps. There should be no change.

OK, I understand that node-reuse can help speed up design. However, is there a chance that MSBuild can periodically unload dll
s and libraries it no longer needs (such as if it's not presently in the 'Building' state?)

This "feature" causes massive problems for CI. A little tweak to "periodically unload unused dll's" would be a great improvement. You are correct, node reuse is a massive overhead saver. However, it does not need to hang on to DLLs, e.g., for NuGet packages, when not in the Building state.

Just to be clear, the perf effect is only to save a few 100ms at the build start. As such it is not relevant in CI at all and IMO should always be disabled there. Perhaps in retrospect it would have been better to be opt-in and VS could opt in.

Maybe make it a Tools -> Options check box?

-Brian

On 03/01/2021 11:43 AM Dan Moseley <[email protected]> wrote:

Just to be clear, the perf effect is only to save a few 100ms at the build start. As such it is not relevant in CI at all and IMO should always be disabled there. Perhaps in retrospect it would have been better to be opt-in and VS could opt in.
鈥擸ou are receiving this because you commented.Reply to this email directly, view it on GitHub, or unsubscribe.

Just FYI another option is to disable it in Directory.Build.rsp. See an example here: https://github.com/microsoft/MSBuildSdks/blob/50c49ad46b29f017626510061ef51a1c194f4874/Directory.Build.rsp#L4

This will affect all command-line only builds and not VS.

Was this page helpful?
0 / 5 - 0 ratings