[Xamarin.Android.Build.Tasks] close XAAssemblyResolvers
by jonathanpeppers · Pull Request #9531 · dotnet/android (original) (raw)
Context: https://discord.com/channels/732297728826277939/732297916680765551/1308554103206580244
Fixes: #9133
Context: 86260ed
Various customers have been reporting UnauthorizedAccessExceptions
in incremental builds, which seems to be a new problem in .NET 9. We were not able to reproduce the issue locally, but with the number of reports it seems to be a real issue.
One customer shared a MSBuild.dmp
file (while the file was locked), where I could observe the objects in memory:
MemoryMappedViewStream 132
Mono.Cecil.PE.Image 100
Mono.Cecil.ModuleDefinition 100
Mono.Cecil.TypeDefinition 100
Mono.Cecil.TypeDefinition[] 100
List<Mono.Cecil.TypeDefinition> 1
Xamarin.Android.Tasks.NativeCodeGenState [Static variable Xamarin.Android.Tasks.NativeCodeGenState.<Template>k__BackingField] 1
Then realized the problem was:
- We opened some
.dll
files withMono.Cecil
. - They were never closed.
- Future incremental build attempts would fail on various operations of the same
.dll
files.
We were also storing some static state (NativeCodeGenState
) to be shared across multiple MSBuild tasks:
public static NativeCodeGenState? Template { get; set; }
NativeCodeGenState
also holds a XAAssemblyResolver
in a Resolver
property. This means this XAAssemblyResolver
instance would also be kept alive.
It appears we only use the static Template
property for a bool
flag, so I changed the property to a bool
instead.
After this change, we can safely dispose Resolver
instances. I looped over the NativeCodeGenState
instances disposing of each Resolver
at the end of the <GenerateJavaStubs/>
MSBuild task.