What does “access to disposed closure” mean here?

2019-08-11 13:04发布

问题:

Why does Resharper warn me about "access to disposed closure" in the following code sample:

using (SqlCommand command = new SqlCommand())
{
    command.Parameters.Add("@temp", SqlDbType.VarChar);
    Action<string> action = str =>
        {
            command.Parameters["@temp"].Value = string.Empty;
        };
}

I don't use delegate outside using statement... How to fix this?

回答1:

You are referencing command in action, you can use action in somewhere else then in using and reference to disposed command.

Resharper is telling you that you can access to disposed closure, because using action outside using will cause that. Avoid using disposable object like that, of course it will throw NullReferenceException, but it can be difficult to find the real problem.



回答2:

This code:

Action<string> action = str =>
{
    command.Parameters["@temp"].Value = string.Empty;
};

defines a delegate variable action that uses command. A delegate is a method definition that can be passed around as a variable and called somewhere else using action.Invoke(). Command is a disposable closure.

The reason Resharper flags this is because this code does not directly indicate at what point in time this delegate will actually be invoked. It is possible, in principle, that the definition of the delegate will be around (and will be invoked) after command has been disposed.

Resharper 8.1, the most recent version as of this writing, is not able to determine that this delegate cannot really be invoked from somewhere else.