Web API - 如何正确释放 SQL 连接



我有一个简单的Web API控制器:

public class CarsController : ApiController
{        
    public SqlConnection Db { get; set; }
    public CarsController()
    {            
        Db = new SqlConnection("XXX");
    }
    public async Task<IEnumerable<Car>> GetAll()
    {
        //Fetch cars from DB...            
    }
    protected override void Dispose(bool disposing)
    {
        if (disposing)
            Db.Dispose();
        base.Dispose(disposing);
    }
}

我将 dispose 代码放在 Dipose() 覆盖中,因为我想写一次

  • 我可以确定在任何情况下都会调用释放代码吗?(例外情况示例)。

  • 我能否确定控制器将在号召性用语已完成,释放资源以应对即将推出调用。

  • 如果没有,是否有更强大/正确的方法来做到这一点?

通过使用Dispose(),您正在等待 GC 清理控制器。在 async Task 方法中使用 Using 语句,对象将立即被释放。无论是否异常,sqlConnection 对象都将被释放。您应该在async Task中实例化SqlConnection而不是构造函数,以有效地使用Using

也许你应该考虑使用依赖注入容器,以便控制 IDbConnection 实例化。特别是,查看生命周期管理器和 HierarchicalLifetimeManager。

这样,您就可以摆脱以每个请求的方式手动管理对象处置。

一个良好的开端

我认为您想使用此处概述的方法:在 Web API 请求结束时释放资源。

Web API 框架提供了方法 HttpRequestMessage.RegisterForDispose,允许您注册要在请求结束时释放的任何和所有引用。所以你的代码看起来像这样:

public class CarsController : ApiController
{        
    public SqlConnection Db { get; set; }
    public CarsController()
    {            
        Db = new SqlConnection("XXX");
        Db.Open();
        Request.RegisterForDispose(Db);
    }
    public async Task<IEnumerable<Car>> GetAll()
    {
        //Fetch cars from DB...            
    }
}

在我的项目中,我正在为所有控制器创建一个基类,在其中初始化数据库连接并注册它们以进行处置。因此,我不仅不会为我的操作编写任何 SqlConnection 样板,也不会为任何控制器编写。

最新更新