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

System.Web.Mvc中IControllerFactory创建的控制器未被释放的原因

控制器实例未释放的原因与修复方案

核心问题在于你只实现了IControllerFactory接口的CreateController方法,却没有实现ReleaseController方法,导致ASP.NET MVC框架无法正确回收控制器实例。

在ASP.NET MVC的请求生命周期中,默认控制器工厂(如DefaultControllerFactory)会在请求处理完成后,调用ReleaseController方法来完成控制器的资源清理:如果控制器实现了IDisposable接口,工厂会自动触发其Dispose方法,释放托管/非托管资源,同时让GC能够正常回收实例。而你的自定义SystemConfig类仅完成了控制器的创建逻辑,完全跳过了回收步骤,所以每个请求生成的控制器实例会一直驻留在内存中,直到应用池强制回收。

修复步骤

  • 在SystemConfig类中实现ReleaseController方法:
public class SystemConfig : IControllerFactory
{
    // 已有的CreateController方法...

    public void ReleaseController(IController controller)
    {
        // 检查控制器是否实现IDisposable,若实现则调用Dispose
        if (controller is IDisposable disposable)
        {
            disposable.Dispose();
        }
    }

    // 还需实现IControllerFactory的GetControllerSessionBehavior方法(如果是MVC 3及以上)
    public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
    {
        // 默认返回Default,可根据需求调整
        return SessionStateBehavior.Default;
    }
}

注:MVC 3及以上版本的IControllerFactory还要求实现GetControllerSessionBehavior方法,否则会编译报错。

  • 确保控制器正确实现IDisposable接口(若持有资源):
    如果你的控制器(如AccountController)持有数据库上下文、文件句柄等需要手动清理的资源,要正确实现IDisposable:
public class AccountController : Controller, IDisposable
{
    private readonly MyDbContext _dbContext;

    public AccountController(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    // 控制器的Action方法...

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // 清理托管资源,比如数据库上下文
            _dbContext.Dispose();
        }
        base.Dispose(disposing);
    }
}

完成以上修改后,请求结束时框架会调用ReleaseController,触发控制器的Dispose逻辑,GC就能正常回收控制器实例,解决内存持续增长的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:02:55