在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 test
和xunit
作为测试框架,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"。
似乎罪魁祸首是使用Buildalyzer.Workspaces
包(v3.2.3)的测试,该测试反过来使用Roslyn (Microsoft.CodeAnalysis.CSharp.Workspaces
)来计算某些代码统计信息。
我注意到测试主机在测试中崩溃了,所以我决定暂时禁用它。从那以后,我们也再也没有看到卫星组装查找升起FileNotFoundException
了。我假设某种程度上"平行建筑"Roslyn干扰了正在运行的测试
我没有证据,但这是经验告诉我的。此外,如果再次激活测试,其他零星问题开始再次出现(包括FileNotFoundException
)。在我看来,Roslyn包不应该作为测试套件的一部分并行执行。