在这个c#EF场景中我是否需要担心垃圾收集?

时间:2012-05-18 19:00:15

标签: c# memory-leaks exception-handling using

try
{
  using (MapDataContainer ent = new MapDataContainer()) //is an autogen'd EF object
  {
     //do some stuff, assume it throws an error
  }
}
catch(Exception ex) //catching outside using not sure if IDispose called
{
  //handle error
}

通常我理解在EF对象上使用了IDispose。所以假设它引发了一个异常......这是一个可能的内存泄漏情况吗?

3 个答案:

答案 0 :(得分:6)

你很好。 “使用”实际上是一种尝试......最终是伪装。

答案 1 :(得分:2)

using语句实际上是

ResourceType resource = expression;
try {
   statement;
}
finally {
   if (resource != null) ((IDisposable)resource).Dispose();
}

如您所见,始终会调用Dispose。唯一的例外是如果它是一个CLR错误,但在这种情况下你还是运气不好。

答案 2 :(得分:2)

正如MSDN所说,using语句由C#编译器翻译为try-finally阻止以确保调用IDisposable.Dispose():

{
  MapDataContainer ent = new MapDataContainer();
  try
  {
    ...
  }
  finally
  {
    if (ent != null)
      ((IDisposable)ent).Dispose();
  }
}

没有调用IDisposable.Dispose()的唯一情况是在使用语句块内部调用Environment.FailFast时或者在MapDataContainer()的构造函数内部或后面抛出异常时,但是这仍然没有防止垃圾收集器收集此对象。另外,实现IDisposable的对象通常(但不一定)在析构函数中调用IDisposable.Dispose(),以确保即使在程序员忘记手动调用它或将其包装在using语句中也能正确释放任何非托管资源。