首页 > 解决方案 > 加载卫星程序集时的并发问题?

问题描述

在我们的 CI 中,我们有时会收到以下错误:

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)

到目前为止,我们从未在生产或本地开发机器上看到过这种异常。它仅在测试执行期间出现在 CI 上(使用dotnet testwithxunit作为测试框架和mcr.microsoft.com/dotnet/sdk:5.0.401基础映像)。由于我们只是偶尔看到这个错误,而且大多数测试都是并行运行的,所以我相信这可能是一个并发问题。

有没有人知道这是什么原因(以及补救措施)?

一些上下文:我们在代码中试图实现的是获取本地化资源的流。所以我们正在做类似的事情:

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

language这种情况下是“en-US”。

标签: c#.net-5system.reflectionasp.net-core-localization

解决方案


罪魁祸首似乎是使用Buildalyzer.Workspaces包 (v3.2.3) 的测试,该包又使用 Roslyn ( Microsoft.CodeAnalysis.CSharp.Workspaces) 来计算某些代码统计信息。

我注意到该测试中的测试主机崩溃了,所以我决定暂时禁用它。从那以后,我们也再没有看到卫星组件查找提高FileNotFoundException了。我假设 Roslyn 确实以某种方式干扰了正在运行的测试的“并行构建”。

我没有证据证明这一点,但这就是经验表明的。此外,如果再次激活测试,其他零星问题会再次出现(包括FileNotFoundException)。在我看来,Roslyn 包不一定应该作为测试套件的一部分并行执行。


推荐阅读