在 Filip Ekberg 的《.NET 异步编程入门》一书中,在“异步编程深入探讨/使用附加和分离的任务”一章中,他说通过在异步匿名方法中使用
service
值,引入了一个闭包和不必要的分配。
接下来,他说最好将
services
作为参数传递给StartNew
方法的操作委托,这样可以避免闭包而避免不必要的分配。
我的问题是:
作者说通过将services
作为参数传递,可以实现什么样的分配?
为了更方便地进行调查,我选取了一个简单得多的例子,并将其放在了sharplab.io
中:
Not passing the parameter:
using System; public class C { public void M() { var i = 1; Func<int> f = () => i + 1; f(); } }
which compiles to:
public class C { [CompilerGenerated] private sealed class <>c__DisplayClass0_0 { public int i; internal int <M>b__0() { return i + 1; } } public void M() { <>c__DisplayClass0_0 <>c__DisplayClass0_ = new <>c__DisplayClass0_0(); <>c__DisplayClass0_.i = 1; new Func<int>(<>c__DisplayClass0_.<M>b__0)(); } }
There are two allocations, one for the generated class and one for the
Func<int>
delegate.Passing the parameter:
using System; public class C { public void M() { var i = 1; Func<int, int> f = (x) => x + 1; f(i); } }
which compiles to:
public class C { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<int, int> <>9__0_0; internal int <M>b__0_0(int x) { return x + 1; } } public void M() { int arg = 1; (<>c.<>9__0_0 ?? (<>c.<>9__0_0 = new Func<int, int>(<>c.<>9.<M>b__0_0)))(arg); } }
Here, there are still two allocations, one for the generated class (note there's a static field in the class which creates an instance of the class) and another allocation for the
Func<int>
delegate.
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
public int i;
这确实会增加分配的大小,因为生成的类占用的内存比第二种情况要多。
我理解得对吗?这是作者所指的吗?