是否需要手动执行DataContext的Dispose方法?
来源:互联网 发布:matlab for mac 10.12 编辑:程序博客网 时间:2024/05/16 00:45
我们知道DataContext实现了IDisposable接口。在C#中,凡是实现了IDisposable接口的类,都推荐的使用using语句。如下:
using (DataContext db = new DataContext(fileOrServerOrConnection))
{
//...
}
使用using语句可以确保以正确的方式调用Dispose方法,即使在语句块中出现异常,Dispose方法也将被执行。
但当我们使用如下代码时,将不可避免地得到“System.ObjectDisposedException: 无法访问已释放的对象”异常:
static void Main()
{
var products = GetProductByPrice(20);
foreach (var p in products)
{
// ...
}
}
private static IEnumerable<Product> GetProductsByPrice(decimal price)
{
using (NorthwindDataContextDataContext db = new NorthwindDataContextDataContext())
{
var product = from p in db.Products
where p.UnitPrice >= price
select p;
return product;
}
}
由于延迟加载的特性,LINQ to SQL其实并没有真正查询数据库,而会将实际查询放到遍历时才进行(在Table.GetEnumerator方法内部调用SqlProvider的 Execute方法)。而此时DataContext早已Dispose,自然无法访问。
解决此问题有两种方法:
GetProductsByPrice方法返回时执行ToList方法,这将立即执行查询。
不手动Dispose。这样将会在遍历的时候执行查询。
使用方法1等于摒弃了延迟查询的优势,而使用方法2,是否会对系统造成过多的负载呢?
对此,我翻阅了一些资料,发现尽管有的支持手动Dispose的方式,但更多的则认为没有必要这么做:
Linq DataContext and Dispose
About Disposing the DataContext
ASP.NET MVC Tip #34 – Dispose of Your DataContext (or Don’t)
我们用Reflector打开DataContext,可以看到在其Dispose方法中调用了SqlProvider的Dispose方法。而 SqlProvider.Dispose方法主要任务是关闭数据库连接(调用 SqlConnectionManager.DisposeConnection方法,再跟下去可以发现实际上最终是调用了 SqlConnection.Close方法),剩下的无论是在DataContext还是SqlProvider的Dispose方法中,都只是将一些对象置为null。
而DataContext其实已经将数据连接的打开和关闭管理得井井有条了。在DataContext.SubmitChanges方法中可以看到,在finally块中调用了SqlConnection.Close方法。而负责执行查询的DataContext.ExecuteQuery方法跟踪到最后也会在SqlProvider.Execute方法的finally块中调用SqlConnectionManager的 ReleaseConnection方法。也就是说在我们手动Dispose DataContext的时候,其实主要工作早已经执行完了,剩下的只是清空一些对象所占用的内存,使它们尽早被GC回收。除此之外,DataContext.Dispose再没有其他好处了。并且我们会发现SqlConnectionManager的 ReleaseConnection方法所执行的内容甚至比CloseConnection还要多。
因此我们得出结论,在使用LINQ to SQL时,完全没有必要手动执行DataContext的Dispose方法,更没有必要使用using语句。
- 是否需要手动执行DataContext的Dispose方法?
- 是否需要手动执行DataContext的Dispose方法?
- DirectX 3D中某些对象的释放需要手动调用Dispose方法
- Linq DataContext and Dispose
- SqlConnection的Dispose()方法
- .NET 的 Dispose 方法
- Context3D类的dispose方法
- dispose();不是ActionListener的方法
- DataContext.ExecuteQuery的两种方法调用
- Dispose()方法
- Dispose()方法
- 手动执行java命令的四种方法总结(类,jar包的手动执行)
- Android应用程序是否需要手动退出
- 文件操作的writelines方法-需要手动加入换行符
- 是否需要覆盖ContentProvider的getType方法?
- 是否需要覆盖ContentProvider的getType方法?
- 是否需要覆盖ContentProvider的getType方法?
- 关于Eclipse 的Image 和dispose 方法
- 检测windows 32位程序是否运行在64位系统上
- 匹配中文字符的正则表达式: [/u4e00-/u9fa5]
- Oracle数据库的安装
- ubuntu 下的java 环境的配置、简单的编译与运行
- 用struts标签判断通过request传递的是否有值
- 是否需要手动执行DataContext的Dispose方法?
- 转载: 深入理解iPhone委托模式兼谈iPhone生命周期
- final 关键字
- 冒泡排序_php版本-交换排序法!
- 学习笔记 - Css
- 卷积
- PHP魔术函数__autoload机制介绍
- Java基础-String的比较(==和equal)
- test