Concurrency issue when loading satellite assembly?
Asked Answered
H

1

1

In our CI, we sometimes get the following error:

System.IO.FileNotFoundException : Could not load file or assembly '<our-assembly-name>.resources, Version=1.0.0.0, Culture=en-US, PublicKeyToken=null'. The system cannot find the file specified.
    at System.Reflection.RuntimeAssembly.InternalLoad(ObjectHandleOnStack assemblyName, ObjectHandleOnStack requestingAssembly, StackCrawlMarkHandle stackMark, Boolean throwOnFileNotFound, ObjectHandleOnStack assemblyLoadContext, ObjectHandleOnStack retAssembly)
    at System.Reflection.RuntimeAssembly.InternalLoad(AssemblyName assemblyName, RuntimeAssembly requestingAssembly, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, AssemblyLoadContext assemblyLoadContext)
    at System.Reflection.RuntimeAssembly.InternalGetSatelliteAssembly(CultureInfo culture, Version version, Boolean throwOnFileNotFound)
    at System.Reflection.RuntimeAssembly.GetSatelliteAssembly(CultureInfo culture, Version version)
    at System.Reflection.RuntimeAssembly.GetSatelliteAssembly(CultureInfo culture)

So far we've never seen this exception in production or on a local development machine. It only occurs on the CI during test execution (using dotnet test with xunit as testing framework and mcr.microsoft.com/dotnet/sdk:5.0.401 as base image). Since we see this error only now and then and most of the tests run in parallel, so I'm led to believe that this might be a concurrency issue.

Does anybody have an idea what would be the cause of (and thus also the remedy for) this?

Some context: what we are trying to achieve in our code is to get the stream for a localized resource. So we are doing something like:

var assembly = Assembly.GetExecutingAssembly()
    .GetSatelliteAssembly(CultureInfo.CreateSpecificCulture(language)); // this sometimes crashes
using (Stream stream = assembly.GetManifestResourceStream(resourceName))  { ... }

where language in this case is "en-US".

Halation answered 25/10, 2021 at 11:34 Comment(3)
If you're running multiple dotnet test instances in parallel, you might need to add the --no-build option, to prevent that you have parallel builds at the same time as parallel test runs.Boru
@Boru unfortunately, I'm not. I'm first doing a dotnet build followed by a dotnet test <our.csproj> and there-in, the error is thrown.Halation
Hmm, still I would try whether --no-build fixes the issue. You don't need to (attempt to) build a second time.Boru
H
0

It seems that the culprit was a test that was using the Buildalyzer.Workspaces package (v3.2.3) which in turn uses Roslyn (Microsoft.CodeAnalysis.CSharp.Workspaces) to compute certain code statistics.

I've noticed a crash of the test host in that test and so I've decided to disable it for the time being. Since then, we also haven't seen the satellite assembly look-up raise a FileNotFoundException anymore. I'm assuming that somehow the "parallel build" that Roslyn does interfered with the running tests.

I don't have a proof for this but this is what the experience shows. Also, if a activate the test again, other sporadic problems start showing up again (including the FileNotFoundException). It seems to me that the Roslyn packages shouldn't necessarily be executed in parallel as part of a testing suite.

Halation answered 5/11, 2021 at 17:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.