Did you ever feel like Visual Studio is rebuilding projects every single time, even when there were no changes to the code?
We can build, change nothing, build again and there we go… VS is starting a build instead of saying all my projects are up to date.
Also, there’s that nagging feeling that even when we do change something, VS is building way more projects that it needs.
Like most things I do in life, frustration led me to look further into this matter.
Divide and Conquer
We have two different issues here:
1) VS rebuilds projects even though they haven’t changed.
2) When something did change, VS tends to build more projects than needed.
So let’s tackle both of these issues.
VS rebuilds projects even though they haven’t changed
There are several reasons I know of, that cause this phenomenon. Luckily, we can fix all of them and save an extra minute, 20 times a day.
The most important thing to know here is how to discover the issues.
In your solution, go to Tools -> Options. Choose Projects and Solutions -> Build and Run and select Diagnostic in “MSbuild project build output verbosity”.
This will make the build slower, but will show why there’s a need to a rebuild.
Every time there’s a need to rebuild a project, you will see this kind of message:
In the Output window we can see what is being rebuilt and why.
Here for example, we see that we have a picture with “Copy always” attribute.
Let’s go over some common problems that make this happen.
Resource is set to “Copy always”This is the example we just saw. “Copy always” means just what it says, and there’s never a good reason for that. There’s an option to Copy if newer instead of “Copy always”. We can find the resource file in the Solution Explore. Press F4 to see the properties and change the “Copy to output directory” field.
A reference with CopyLocal set to true, but unused in a VSIX projectI think this happens only with Visual Studio extensions (VSIX projects). When referencing a project in an extension, there’s no need to Copy local since the VSIX file embeds everything in it. If it is set to True in the CopyLocal field (in reference properties) we might experience this problem. Simply setting CopyLocal to False solves this.
Circular dependencyHaving a circular dependency in a .NET project is a bit difficult. VS prevents us from referencing a project directly. However, we can reference to a .dll file in the project’s output. Suppose we have a project A that references project B. In project B we can add a reference to A’s output file path(..A\bin\Debug\A.exe). And here you go, a beautiful circular dependency. This will cause both projects to be rebuilt every time. There’s no workaround here, we’ll have to get rid of the circular dependency.
These are the reasons I know of that cause this problem. If you encountered more reasons, please comment about them and I’ll add them to the post. Now let’s see what we can do about that other issue.
When something did change, VS tends to build more projects than needed.This is not just a feeling. MSBuild works in a specific way that sometimes does more work than it should. Here’s the problematic scenario: Suppose we have a project A that references project B. In project B we have a public function Foo() which project A uses. If we change the signature of Foo() to Foo(int x), then A has to be built again. However, if we change the internal logic inside Foo(), there’s no reason for A to be built. Just B. But MSBuild will rebuild A anyway. (And all other projects referencing B) I believe MSBuild simply works according to date modified. If A references B, and B was modified after A .dll was modified, then MSBuild will build A as well.
What can we do about it?ReSharper Build supposedly solves this problem. And I believe it comes with ReSharper out of the box, no extra license required. ReSharper Build has other cool features that will make your build much faster. I haven’t gotten around to trying it as I wanted a solution that will work even for team members who don’t have ReSharper installed, but since my manager swears by it, I thought it is worth a mention J The silver lining here is that Microsoft are aware of this issue and claim they fixed it. It should be included in some future version of Visual Studio.
SummaryFor me, those extra unnecessary build times are really annoying and I feel compelled to fix them. It’s easy to get lazy about making these improvements as no-one likes to mess about with MSBuild, but do it once and it will save you tons of time in the long run. On top of that, it’s really time saved for the entire team.
Ozcode Visual Studio Extension
Elevate LINQ debugging with visibility, clarity and insights into your queries.
Time travel to see how your code will execute before you step through it.
Heads-up display gives you powerful visualizations so you can instantly understand what’s happening in your code.
Data tips provide deep insights into your data letting you drill down to any level in a data object.