You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7中AssemblyLoadContext的LoadFromAssemblyPath无法后续卸载问题

.NET 7 WPF 动态加载程序集卸载问题解答

这种差异是设计使然,但也和你使用PluginLoader的具体方式直接相关,以下是具体解析:

核心原因差异

  • CollectableAssemblyLoadContext(CALC)+ MemoryStream加载:
    CALC的核心设计目标就是支持程序集卸载,通过MemoryStream加载时,程序集字节被完全加载到内存,与磁盘文件无绑定关系。只要你确保没有任何跨上下文的强引用(比如主应用上下文持有CALC中程序集的类型实例、静态引用等),CALC就能正确跟踪并释放所有相关资源,实现卸载。

  • PluginLoader + LoadFromAssemblyPath加载:
    如果你使用的PluginLoader是基于默认AssemblyLoadContext或者非可回收的自定义上下文加载程序集,那么抛出“不可回收程序集”异常是预期行为——因为默认上下文本身是不可回收的,一旦程序集加载到默认上下文,就无法被卸载。

    另外,即便你指定CALC作为加载上下文,LoadFromAssemblyPath也有隐含限制:如果待加载程序集的依赖项已经存在于默认上下文(或其他不可回收上下文),或者加载后的程序集被外部上下文持有强引用,CALC会因为无法满足“无跨上下文引用”的卸载条件,同样触发该异常。

正确实现卸载的操作要点

如果想通过路径加载并实现卸载,必须满足以下条件:

  • 为PluginLoader指定自定义的CollectableAssemblyLoadContext,而非默认上下文。
  • 确保待加载程序集的所有依赖项都完全加载到同一个CALC中,避免依赖默认上下文内的程序集(系统共享程序集除外,它们会被加载到共享上下文,不影响卸载)。
  • 使用完程序集后,彻底释放所有对该程序集中类型、对象的强引用,确保没有引用泄漏到主应用上下文。

示例代码

// 创建可回收的加载上下文
var collectableContext = new CollectableAssemblyLoadContext(isCollectible: true);
try
{
    // 从路径加载程序集到可回收上下文
    var pluginAssembly = collectableContext.LoadFromAssemblyPath(@"D:\MyWpfPlugins\TestPlugin.dll");
    
    // 在这里执行插件逻辑,注意避免将插件内的对象留在主应用的强引用中
}
finally
{
    // 触发卸载
    collectableContext.Unload();
}

总结

LoadFromAssemblyPath本身不限制程序集是否可回收,问题的核心在于承载它的AssemblyLoadContext是否为可回收类型,以及是否满足卸载的前置条件。你遇到的异常,要么是因为使用了不可回收的加载上下文,要么是存在跨上下文的强引用导致无法满足卸载要求。

内容的提问来源于stack exchange,提问作者Boppity Bop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 01:37:45