为何.NET Framework的C#应用会搜索不存在的Resource.dll?如何阻止?
.NET Framework资源DLL无意义搜索的原因与解决办法
运行时搜索这些资源DLL的根源
- 这是.NET Framework资源加载的默认行为:运行时会根据当前线程的
CurrentUICulture和CurrentCulture,自动尝试加载对应区域性的附属资源程序集。哪怕你的EXE没嵌入资源,只要你引用的A、B、C三个主程序集本身定义过附属资源(哪怕这些资源根本没部署),运行时就会按区域性层级去查——先找en-US(特定区域),找不到就降级找en(中性区域),这刚好对应你看到的每种DLL的调用次数。 - 公钥令牌一致是因为A、B、C三个主程序集用同一密钥签名,它们的附属资源程序集会继承这个令牌,运行时靠这个匹配资源和主程序集的归属。
让运行时停止无效搜索的方法
方法一:强制使用中性区域性
如果你的应用不需要多语言支持,在Main方法开头直接设置线程文化为不变区域性,跳过特定区域的资源查找:
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
方法二:通过配置文件禁用
在app.config里添加配置,明确告诉运行时不需要这些资源:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <!-- 对A、B、C分别配置 --> <dependentAssembly> <assemblyIdentity name="A" publicKeyToken="你的公钥令牌" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-999.999.999.999" newVersion="你的程序集版本" /> <publisherPolicy apply="no" /> </dependentAssembly> </assemblyBinding> <!-- 开启绑定失败缓存,避免重复查找 --> <disableCachingBindingFailures enabled="true" /> </runtime> </configuration>
方法三:在AssemblyResolve事件中直接返回null
如果还需要保留事件处理,遇到这些无效资源请求时直接返回null,告诉运行时该资源不存在:
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var assemblyName = new AssemblyName(args.Name); if ((assemblyName.Name is "A.resources" or "B.resources" or "C.resources") && (assemblyName.CultureName is "en-US" or "en")) { return null; } // 其他请求按原有逻辑处理,没有就返回null return null; };
方法四:清理引用程序集的资源定义
如果A、B、C是你自己开发的程序集,重新编译时移除无用的资源文件;如果是第三方库,查文档看有没有开关可以禁用资源加载。
内容的提问来源于stack exchange,提问作者Sabuncu
相关产品推荐
相关产品推荐

