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

如何强制AssemblyLoadContext卸载以实现ASP.NET 5应用的自更新功能?

问题根因

你遇到的可回收AssemblyLoadContext无法卸载的核心原因主要来自几个常见场景:

  1. 自定义ALC的加载逻辑有错误,部分程序集被加载到默认ALC,产生跨上下文强引用
  2. ASP.NET Core主程序停止后未正确释放所有资源,遗留对象持有ALC实例引用
  3. 未销毁的后台线程、静态缓存、定时器、非托管资源持有引用

修复步骤

1. 修正HostAssemblyLoadContext的加载逻辑

你当前的Load方法里使用了Assembly.LoadFrom(filePath),这个API会将程序集加载到默认全局AssemblyLoadContext,而非你自定义的可回收ALC,会直接产生跨上下文引用,导致自定义ALC永远无法被卸载。修改为调用当前ALC的加载方法:

protected override Assembly? Load(AssemblyName name)
{
    string? assemblyPath = _resolver.ResolveAssemblyToPath(name);
    if (assemblyPath != null)
        return LoadFromAssemblyPath(assemblyPath);

    string filePath = $"{name.FullName.Split(',')[0]}.dll";
    if(File.Exists(filePath))
        // 替换Assembly.LoadFrom为当前ALC的加载方法
        return LoadFromAssemblyPath(filePath);

    return null;
}

2. 显式释放ASP.NET Core的IHost实例

你当前的ASP.NET主程序只调用了Run(),Run方法返回后没有主动Dispose IHost实例,大量DI容器资源、Kestrel线程、后台托管服务都不会被主动释放。修改主程序Main方法:

public static void Main(string[] args)
{
    Console.Out.WriteLine("Starting Server...");
    // 用using声明,IHost运行结束后自动释放所有关联资源
    using var host = CreateHostBuilder(args).Build();
    host.Run();
    Console.Out.WriteLine("Server stopped.");
}

3. 优化GC回收逻辑

部分需要终结的对象可能需要多轮GC才能完全释放,调整回收逻辑确保所有代的对象都被回收:

for (int i = 0; weakReference.IsAlive && i < 20; i++)
{
    GC.Collect(2, GCCollectionMode.Forced, true, true);
    GC.WaitForPendingFinalizers();
    GC.Collect(2, GCCollectionMode.Forced, true, true);
}

4. 残留引用定位方法

如果修改后仍然无法卸载,可以用VS内存调试工具定位引用根:

  1. 在loadContext.Unload()执行后打断点
  2. 调试状态下拍摄内存快照
  3. 搜索HostAssemblyLoadContext类型的实例,查看其强引用根,即可定位到持有引用的对象/线程。

更稳定的替代方案

ASP.NET Core本身设计了大量静态缓存、后台线程,和ALC卸载的兼容性非常差,更推荐你使用进程级别的更新方案,完全规避ALC卸载的复杂问题:

  • 宿主进程检测到更新后,优雅停止ASP.NET服务
  • 宿主启动独立的更新助手进程,传入自身进程ID
  • 宿主进程主动退出,更新助手等待宿主进程完全退出后替换所有DLL
  • 替换完成后更新助手重新启动宿主进程,自动退出
    该方案兼容性100%,适配你提到的Windows服务、Linux systemd、Docker等所有部署场景。

内容的提问来源于stack exchange,提问作者Lázár Zsolt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:09:04