Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed build leaves MSBuild processes lying around #1709

Closed
wjk opened this issue Feb 16, 2017 · 15 comments
Closed

Failed build leaves MSBuild processes lying around #1709

wjk opened this issue Feb 16, 2017 · 15 comments
Labels

Comments

@wjk
Copy link

wjk commented Feb 16, 2017

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.

@AndyGerlicher
Copy link
Contributor

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.

@mpseidel
Copy link

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.

@gabrielpra1
Copy link

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

I'm also using FodyPropertyChanged and VS2017.

@mpseidel
Copy link

mpseidel commented Nov 7, 2017

@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

@fedeazzato
Copy link

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?

@djonasdev
Copy link

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!

@gabrielpra1
Copy link

gabrielpra1 commented May 24, 2018

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

@kjkrum
Copy link

kjkrum commented Nov 20, 2018

@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.

@kjkrum
Copy link

kjkrum commented Nov 21, 2018

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.

@francisrohner
Copy link

@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.

@astrohart
Copy link

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.

@danmoseley
Copy link
Member

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.

@astrohart
Copy link

astrohart commented Mar 1, 2021 via email

@AndyGerlicher
Copy link
Contributor

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.

@Algorithman
Copy link

When will this be fixed on a per project level? This issue is known and was called out since VS2008 every year.

It can't really be that hard. The MSBuild processes started by Visual Studio are explicitly called WITH then /nodeReuse:true argument.

I'm quite sick and tired of this issue. Had it a few times over the years and every time i look for a solution which doesn't require me to set a global environment variable does work only for MSBuild from the commandline but not in VS.

Bad, Microsoft, very bad. No, really, very bad.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests