Ninject Transient Scope + Scope Disposal + Garbage Collection + Memory Leak

时间:2013-07-16 04:14:37

标签: memory-leaks garbage-collection asp.net-web-api ninject

我是新手(我还在学习),如果绝地大师可以帮助我解决我的问题和关注,我将非常感激。

我想使用Ninject,我有下面的代码,我想知道我的对象是否会被正确处理并收集垃圾。

对于Ninject的默认Transient Scope,我读到“Lifetime不是由内核管理的(Scope对象为null),永远不会被Disposed。”

如果我要在生产中使用我的代码,特别是当我对WebApi(POST)进行大量并发调用时,是否会导致内存泄漏等问题?

在这种情况下,Ninject的最佳对象范围是什么?

顺便说一下,如果我没有像“kernel.Bind()。To();”那样指定对象范围,它会默认为TransientScope吗?

public class VehicleClassRepository : IVehicleClassRepository
{
    SomeDataContext context = new SomeDataContext();

    public IQueryable<VehicleClass> All
    {
        get { return context.VehicleClasses; }
    }

    public IQueryable<VehicleClass> AllIncluding(params Expression<Func<VehicleClass, object>>[] includeProperties)
    {
        IQueryable<VehicleClass> query = context.VehicleClasses;
        foreach (var includeProperty in includeProperties) {
            query = query.Include(includeProperty);
        }
        return query;
    }

    public VehicleClass Find(int id)
    {
        return context.VehicleClasses.Find(id);
    }

    public void InsertOrUpdate(VehicleClass vehicleclass)
    {
        if (vehicleclass.VehicleClassId == default(int)) {
            // New entity
            context.VehicleClasses.Add(vehicleclass);
        } else {
            // Existing entity
            context.Entry(vehicleclass).State = EntityState.Modified;
        }
    }

    public void Delete(int id)
    {
        var vehicleclass = context.VehicleClasses.Find(id);
        context.VehicleClasses.Remove(vehicleclass);
    }

    public void Save()
    {
        context.SaveChanges();
    }

    public void Dispose() 
    {
        context.Dispose();
    }
}

public interface IVehicleClassRepository : IDisposable
{
    IQueryable<VehicleClass> All { get; }
    IQueryable<VehicleClass> AllIncluding(params Expression<Func<VehicleClass, object>>[] includeProperties);
    VehicleClass Find(int id);
    void InsertOrUpdate(VehicleClass vehicleclass);
    void Delete(int id);
    void Save();
}

在我的NinjectWebCommon.cs中:

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IVehicleClassRepository>().To<VehicleClassRepository>();
    }   

在我的WebApi的VehicleClassController.cs中:

public HttpResponseMessage Post(VehicleClass value)
{
        if (value == null)
        {
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }
        else
        {
            vehicleclassRepository.InsertOrUpdate(value);
            vehicleclassRepository.Save();
            return new HttpResponseMessage(HttpStatusCode.Created);
        }
}

1 个答案:

答案 0 :(得分:1)

迟到的答案(差不多2年)但是如果其他人读到这个......

虽然垃圾收集器最终会处理你的VehicleClassRepository实例,但在此之前你很可能会遇到问题。

您的数据上下文可能会保持打开的数据库连接,直到它被处理掉。 db连接可能来自数据库连接池。

在CLR最终垃圾收集这些(也会处理它们)之前很久,传入的请求在尝试获取数据库连接时最终阻塞,但没有可用的。

我遇到过这种行为,并从中学到了很多困难。因此,VehicleClassRepository应该在依赖范围内确定范围,以便每次调用获得一个,更重要的是,它将在调用完成后立即处理。