What does “Access to disposed closure” mean?

2019-02-22 02:11发布

I have the following code:

public void DequeueRecipe(AuthIdentity identity, params Guid[] recipeIds)
{
   using (var session = GetSession())
   {
      var recipes = (from r in recipeIds select new Models.Recipes {RecipeId = r}).ToArray();

      var dbRecipes = session.QueryOver<Models.QueuedRecipes>()
         .Where(Expression.Eq("UserId", identity.UserId))
         .Where(Expression.InG("Recipe", recipes))
         .List<Models.QueuedRecipes>();

      using (ITransaction transaction = session.BeginTransaction())
      {
         dbRecipes.ForEach(r => session.Delete(r)); // <-- Warning
         transaction.Commit();
      }
   }
}

reSharper is giving me the warning:

Access to disposed closure

On the line:

dbRecipes.ForEach(r => session.Delete(r));

(The session variable is underlined as the culprit).

While it's true the ForEach method takes a lamba expression which creates a closure around the variable session, I don't see a way where it would possibly be disposed when this code is executed. Perhaps reSharper thinks ForEach might execute some sort of task in parallel, or save that Action<> for a later time, thus technically it might be disposed while the anonymous function is still reachable in memory.

Am I safe the ignore this warning? Is there a way I can reformat my code to prevent this warning from appearing? Is there indeed a danger presented by this code?

I'm used to reSharper being smarter than me, so I'd like to understand exactly what's going on.

1条回答
【Aperson】
2楼-- · 2019-02-22 02:41

Because session is wrapped in a using statement, and the LINQ execution could be defered until it is enumerated.

Resharper is warning that this could result in an exception, because by the time dbRecipes is enumerated, the session could have have been disposed.

I'll be honest: I'm not sure the above code could ever fail in the way warned about.

查看更多
登录 后发表回答