简体   繁体   中英

Do I have to worry about garbage collection in this c# EF scenario?

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
}

Normally I understand that the using called the IDispose on the EF object. So supposing it threw an exception... Is this a possible memory leak scenario?

You're fine. "using" is actually a try..finally in disguise.

The using statement is actually

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

So as you can see, the Dispose is always called. The only exception is if it is a CLR error, but in that case you're out of luck anyway.

As MSDN says, using statement is translated by C# compiler to try-finally block to ensure, that IDisposable.Dispose() is called:

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

The only cases when IDisposable.Dispose() is not called is when Environment.FailFast is called inside using statement block or when exception is thrown inside or right after the constructor of MapDataContainer(), but this still doesn't prevent Garbage collector to collect this object. Additionally objects that implements IDisposable typically (but not necessarily) call IDisposable.Dispose() in destructor to ensure that any unmanaged resources will be correctly released even in programmer forgets to call it manually or wrap it in using statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM