Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么Ninject不使用InCallScope释放已处置的对象?_C#_.net 4.0_Ninject_Ninject Extensions - Fatal编程技术网

C# 为什么Ninject不使用InCallScope释放已处置的对象?

C# 为什么Ninject不使用InCallScope释放已处置的对象?,c#,.net-4.0,ninject,ninject-extensions,C#,.net 4.0,Ninject,Ninject Extensions,我正试图在WinForms应用程序中使用Ninject(版本3.0.1),我有几个(当前)自绑定服务类,我使用Ninject构建它们。某些服务类需要其他服务类(子服务)。大多数服务类都需要一个存储库来与数据库交互,因为我有一个抽象的IRepository接口。我需要为服务类中的整个服务层次结构拥有相同的存储库,因此在绑定IRepository时使用InCallScope()范围。目前我使用XPO作为ORM工具,所以我有一个XpoRepository实现,我将绑定到它。有关此场景,请参阅我的 我的

我正试图在WinForms应用程序中使用Ninject(版本3.0.1),我有几个(当前)自绑定服务类,我使用Ninject构建它们。某些服务类需要其他服务类(子服务)。大多数服务类都需要一个存储库来与数据库交互,因为我有一个抽象的IRepository接口。我需要为服务类中的整个服务层次结构拥有相同的存储库,因此在绑定IRepository时使用
InCallScope()
范围。目前我使用XPO作为ORM工具,所以我有一个XpoRepository实现,我将绑定到它。有关此场景,请参阅我的

我的装订看起来像这样:

Bind<IRepository>().To<XpoRepository>().InCallScope();
while (true) {
    if (CancellatioPending())
        break;
    using (var service = _kernel.Get<Service1>())
    {
        // do some stuff using the service class
    }
    Thread.Sleep(20*1000);
}
我在后台线程(使用TPL)中使用其中一个服务,循环如下:

Bind<IRepository>().To<XpoRepository>().InCallScope();
while (true) {
    if (CancellatioPending())
        break;
    using (var service = _kernel.Get<Service1>())
    {
        // do some stuff using the service class
    }
    Thread.Sleep(20*1000);
}
while(true){
if(cancellationding())
打破
使用(var服务=_kernel.Get())
{
//使用服务类做一些事情
}
线程。睡眠(20*1000);
}
在使用Ninject之前,我有相同的结构,所以我(我认为)正确地实现了对每个对象的处理,包括在正确位置的存储库。然而,我注意到,由于我使用Ninject来实现这一点,我的应用程序中有一个很大的内存泄漏,它每2-3小时就会崩溃一次,OutOfMemoryException。我在循环中放置了一个断点,并注意到Ninject缓存有数千个条目,其中充满了已处理的XpoRepository对象。我猜它们是由我处理的,但我不确定是谁调用了dispose方法

为什么Ninject会持有这些处置过的对象?我希望当我在using块的末尾处理主服务时(由于InCallScope(),这是IRepository对象的作用域),其作用域中的每个对象都应该由Ninject处理和释放


编辑:在任何关于为什么这种模式不好的评论或回答之前,我知道它可能会更好。我知道我可以提取服务接口来实际使用DI并提高可测试性,我还知道我可能应该使用
Func
作为构造函数参数,并将其注入其中,就像每个服务都可以有自己的责任来处理存储库一样。只是我目前没有时间进行这样的重构。

Ninject将发布存储库,前提是以下所有内容都是正确的:

  • 没有人持有对服务1的引用
  • service1本身是GC'd(因为您有20秒的线程睡眠时间,所以很有可能它已升级到gen2,并且很少发布)
  • 缓存修剪是在service1被GC’d之后执行的,缓存修剪间隔默认为30秒。您可能需要尝试更短的间隔时间
  • 与上一点不同,您可以尝试通过在service1中实现
    Ninject.Infrastructure.dispose.INotifyWhenDisposed
    来强制立即发布

另请参见,谢谢您的回答。我该怎么做才能摆脱与20秒睡眠相关的GC行为?我想这可能会导致我的问题。将using提取到另一个方法实际上我在实际代码中有一个单独的方法,我只是不认为这有什么关系。我使用一个“类似计时器”的组件(单线程,这就是为什么我用TPL启动它),它接收一个动作以循环执行。它在每个周期之间使用ad.Sleep。我尝试实现INotifyWhenDisposed接口,通过这种方式缓存被放松,但内存仍然大约为800MB,而且GC似乎不想收集我的对象。显式GC.Collect解决了这个问题,但我不想使用太多。你知道还有什么会导致这种情况吗?