不可回收的 AssemblyLoadContext 中的可回收組件
.NET 錯誤允許將可回收記憶體的組件解析為不可回收的 AssemblyLoadContext。 在某些情況下,這會導致執行階段損毀,或非預期的 NullReferenceException 例外狀況。 當 AssemblyLoadContext.Load(AssemblyName) 或 AssemblyLoadContext.Resolving 事件傳回可回收的 Assembly,且 AssemblyLoadContext 不可回收時,此變更可防止發生錯誤行為。
先前的行為
在 AssemblyLoadContext.Load(AssemblyName) 覆寫時、或在不可回收 AssemblyLoadContext 的 AssemblyLoadContext.Resolving 事件中,傳回可回收的 Assembly 不會導致擲回任何例外狀況。
新的行為
在 AssemblyLoadContext.Load(AssemblyName) 覆寫時、或在不可回收 AssemblyLoadContext 的 AssemblyLoadContext.Resolving 事件中,傳回可回收的 Assembly 會擲回包含 NotSupportedException 的 System.IO.FileLoadException,作為內部例外狀況。
導入的版本
.NET 7
中斷性變更的類型
這項變更會影響二進位相容性。
變更原因
這項變更修正了 Bug。 可回收的 Assembly 會在 AssemblyLoadContext 具有參考時回收記憶體,以供剩餘的處理序存留期使用。 若該情境執行的程式碼,在回收後參考該 Assembly
的任何項目,便會損毀執行階段,或導致 NullReferenceException、AccessViolationException 或其他種類的錯誤行為。
建議的動作
在 AssemblyLoadContext.Load(AssemblyName) 或不可回收 AssemblyLoadContext 的 AssemblyLoadContext.Resolving 事件中,請勿傳回可回收的組件。 可行的因應措施是在建構函式中傳遞 isCollectible
參數的 true
,將 AssemblyLoadContext
變更為可回收,並永遠保留該 AssemblyLoadContext
的參考,以確保永遠不回收。
受影響的 API
- System.Runtime.Loader.AssemblyLoadContext.Load(AssemblyName)
- System.Runtime.Loader.AssemblyLoadContext.Resolving 事件