When I add "/m" to my MSBuild runner's command line arguments in my build configuration in order to get parallel builds, extra MSBuild.exe processes are spawned and reside in memory after the build is over (by design). The trouble is these residual processes hold locks to managed assemblies that they loaded for custom tasks of a prior build. These locks prevent future TeamCity builds from being able to update these DLLs, resulting in a build failure.
I wonder if TeamCity can search for and kill msbuild.exe processes when starting its own build to avoid this problem. Ideally it won't kill active msbuild.exe processes it doesn't own, but that might be impractical.