不可回收的 AssemblyLoadContext 中的可回收程序集
.NET 错误地允许垃圾回收程序集解析为不可回收的 AssemblyLoadContext。 在某些情况下,此操作会导致运行时崩溃或意外出现 NullReferenceException 异常。 此更改通过在 AssemblyLoadContext.Load(AssemblyName) 或 AssemblyLoadContext.Resolving 事件返回可回收的 Assembly 并且 AssemblyLoadContext 不可回收时引发异常来阻止不正确的行为。
旧行为
在 AssemblyLoadContext.Load(AssemblyName) 替代中返回可回收的 Assembly 或不可回收的 AssemblyLoadContext 的 AssemblyLoadContext.Resolving 事件不会引发任何异常。
新行为
在 AssemblyLoadContext.Load(AssemblyName) 替代中返回可回收的 Assembly 或不可回收的 AssemblyLoadContext 的 AssemblyLoadContext.Resolving 事件会引发带有 NotSupportedException 作为内部异常的 System.IO.FileLoadException。
引入的版本
.NET 7
中断性变更的类型
此项更改可能会影响二进制兼容性。
更改原因
此更改修复了一个 bug。 可回收的 Assembly 将被执行垃圾回收操作,而引用它的 AssemblyLoadContext 在进程生存期的剩余时间内仍然存在。 如果在该上下文中运行的代码在收集后引用了 Assembly
中的任何内容,将会导致运行时崩溃或导致 NullReferenceException、AccessViolationException 或其他类型的错误行为。
建议的操作
不要返回 AssemblyLoadContext.Load(AssemblyName) 中的可回收程序集或不可回收的 AssemblyLoadContext 的 AssemblyLoadContext.Resolving 事件。 一种可能的解决方法是将 AssemblyLoadContext
更改为可回收,这可以通过在其构造函数中为 isCollectible
参数传递 true
来实现,然后永久保留对 AssemblyLoadContext
的引用以确保它永远不会被回收。
受影响的 API
- System.Runtime.Loader.AssemblyLoadContext.Load(AssemblyName)
- System.Runtime.Loader.AssemblyLoadContext.Resolving 事件
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈