代码之家  ›  专栏  ›  技术社区  ›  Chris Simpson

为什么即使我显式地处理了DataContext,连接也没有关闭?

  •  5
  • Chris Simpson  · 技术社区  · 16 年前

    我试着在配置中输入Pooling=false以查看是否有任何效果,但没有效果。在任何使用池的情况下,我都不希望每个负载都有一个新的连接,我希望它能重用连接。

    一些代码来说明我上面所说的:

    控制器:

    public class MyController : Controller
    {
        protected MyRepository rep;
    
        public MyController ()
        {
            rep = new MyRepository();
        }
    }
    

    存储库:

    public class MyRepository
    {
        protected MyDataContext dc;
    
        public MyRepository()
        {
            dc = getDC();
        }
    
        ~MyRepository()
        {
            if (dc != null)
            {
                //if (dc.Connection.State != System.Data.ConnectionState.Closed)
                //{
                //    dc.Connection.Close();
                //}
                dc.Dispose();
            }
        }
    
        // etc
    }
    

    注意:为了审计目的,我向DC添加了许多提示和上下文信息。这就是为什么我希望每页加载一个连接

    更新: 在我的存储库和控制器类上实现了IDisposable之后,我找不到方法在我的控制器上具体调用Dispose方法,因为MvcHandler在幕后创建和销毁了控制器。然而,我发现我的连接被关闭无论如何。我不舒服知道这是工作,但不知道为什么,所以我做了一些挖掘,发现了MSDN报价,使我高兴:

    最终更新:

    3 回复  |  直到 16 年前
        1
  •  4
  •   Henk Holterman    16 年前

    正确的模式(简短但足够的版本)是:

    public class MyRepository : IDisposable
    {
        ...  // everything except the dtor
    
        public void Dispose()
        {
            if (dc != null)
            {
                dc.Dispose();
            } 
        }
    }
    
    public class MyController : Controller, IDisposable
    {
        protected MyRepository rep;
    
        public MyController ()
        {
            rep = new MyRepository();
        }
    
        public void Dispose()
        {
           if (rep!= null)
           {
              rep.Dispose();
           } 
        }
    }
    

    现在您可以(应该)在using子句中使用MyController:

    using (var ctl = new MyController ())
    {
       // use ctl
    }
    


    刚刚注意到它级联到MyController,代码补充道。这显示了非托管资源的间接所有权是如何分布的。


    这也是正确的(尝试/最终):

    var ctl = GetController ();
    using (ctl)
    {
       // use ctl
    }
    

        2
  •  2
  •   Community Mohan Dere    9 年前

    析构函数只由GC调用。MyRepository应该实现Dispose模式,并在那里处理dc。

    In C# what is the difference between a destructor and a Finalize method in a class?

    MyRepository应该实现IDisposable,如果您在对象的生命周期内一直将其打开,那么应该在那里处置任何一次性对象。

    大多数时候,当你使用一次性物品时,你应该把它包在一个使用块里

    using(var dc = getDC())
    {
        //do stuff with the dc
    }//the dc will be Disposed here
    

    编辑:链接到c#析构函数的语言指南 http://msdn.microsoft.com/en-us/library/66x5fx1b(v=VS.100).aspx

        3
  •  0
  •   Community Mohan Dere    9 年前

    Henk Holterman Darryl Braaten 是非常好的,我不认为它回答了你潜在的问题。

    This SO Post ,说明何时应该担心关闭连接。。。