使用匿名方法有任何开销吗?

我想知道在创建Background worker时是否通过使用匿名方法产生任何开销。

例如:

public void SomeMethod() { BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += (sender, e) => { //large amount of code } worker.RunWorkerAsync(); } 

上面的例子是否比在单独的方法中定义//large amount of code更好或更差?

在线定义后台工作程序方法是否有任何开销,特别是如果经常调用SomeMethod()

从它们创建委托时,如何处理命名方法和无序方法存在细微差别。

匿名方法的委托被缓存,因此检查委托是否已存在于缓存中的开销很小。 另一方面,如果您多次运行该方法,它将重用缓存的委托而不是创建新的委托。

命名方法的委托不会被缓存,因此每次都会创建。

除此之外没有区别。 anonumous方法将在编译时创建,并且像常规方法一样存在于代码中,只有编译器知道的名称。

首先,您可能不应该将大量代码放入匿名方法中。 如果为这个方法创建一个单独的方法,甚至更好的方法,它会更具可读性。

对于生成的IL,如果lambda没有关闭任何变量,那么生成的IL代码就像将代码放在普通的命名方法中一样(除了生成的方法有一个不可说的名称)。

另一方面,如果关闭某个变量,编译器会创建一个闭包类来将该变量保存在字段中。 并且字段访问比局部变量访问略贵。

总而言之,如果您关闭某些变量,则开销很小(包括需要进行垃圾回收的更多对象)。 在大多数情况下,这并不重要,担心这将是过早的优化。 但如果你认为它确实重要,你应该分析代码。

每当匿名方法(包括lambda)关闭变量时,编译器就会创建一个类来为您保存这些变量。 每当创建委托时,也会创建此类的新实例。 这显然为运行时添加了额外的工作,但在大多数情况下通常可以忽略不计。

我前几天测试了这个(通过使用StopWatch类)。 据我所知,直接调用方法之间没有明显的性能差异……

 SomeMethod(); 

……或通过匿名方法……

 () => SomeMethod(); 

它主要影响可读性 – 一个地方的大量代码几乎从来都不好;-)

在性能方面,请参见何时优化为时过早?

这是反编译员所说的:

 [CompilerGenerated] private static DoWorkEventHandler CS$<>9__CachedAnonymousMethodDelegate1; [CompilerGenerated] private static void b__0(object sender, DoWorkEventArgs e) { throw new NotImplementedException(); } public void SomeMethod1() { BackgroundWorker worker = new BackgroundWorker(); BackgroundWorker backgroundWorker = worker; backgroundWorker.DoWork += (object sender, DoWorkEventArgs e) => throw new NotImplementedException(); worker.RunWorkerAsync(); } public void SomeMethod2() { BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += worker_DoWork; worker.RunWorkerAsync(); } private void worker_DoWork(object sender, DoWorkEventArgs e) { throw new NotImplementedException(); } 

编辑:

查看IL代码,第一次创建/分配方法委派的开销很小。