Closure allocations in C#

不想你离开。 提交于 2020-02-19 09:46:41

问题


I've installed the Clr Heap Allocation Analyzer extension and in a project I see something that I quite don't understand, I've got a method with a signature

public Task<int> ExecuteAsync(string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
    {
        param = SetModificationValuesForGlobalRing(param);
        return _sqlPolicy.ExecuteAsync(async () =>
        {
            int result;
            using (var connection = new SqlConnection(_connectionString))
            {
                await connection.OpenAsync();
                result = await connection.ExecuteAsync(sql, param as object, transaction, commandTimeout, commandType);
            }
            return result;
        });
    }

This tools' giving me a warning on the method and all the parameters that says

The compiler will emit a class that will hold this as a field to allow capturing of this closure.

I don't know why this behaviour happens, is it due to the optional parameters?

--------EDIT Add body to the method ------------


回答1:


You must be:

  1. Calling this code from within an anonymous function, like a lambda.

    • or -
  2. Using the yield/await keyword somewhere.

When you use either of the above, C# must create a closure to capture any variables used within the closure that have an originating scope outside of your lambda (in the first case) or usage before and after the yield/await (in the second case).

C# captures the closure by creating an anonymous class -- defined at compile-time -- in memory. It then creates a field on that anonymous class for each piece of information it needs to persist. This can result in an object instance's lifetime being extended for the life of the closure or the life of the method with the yield/await.

Sometimes the lifetime is longer than had you NOT used yield/await or the lambda. In that case, you might notice memory usage that is higher than you expected (as the garbage collector won't collect the object instance until the closure is completely out of scope or the method containing the yield/await has completed).

The warning you see is simply your tool trying to explain the above to you, so that you know to expect this behavior and the resulting potential increase in memory usage.



来源:https://stackoverflow.com/questions/36271719/closure-allocations-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!