Disclaimer: C# Express/March CTP/.NET version v2.0.50110

This is for the performance concious freaks out there (like me). The following code results in a new Delegate instance being constructed every pass through the loop even in release builds:

private void MyBackgroundWorker(object state)
{
 for(int work = 0; work < 10000; work++)
 {
   this.Invoke(new MethodInvoker(
                   delegate()
                   {
                    this.label1.Text = work.ToString();
                   }));
 }
}

If you disassemble this version and have a look at the IL you'll see the MethodInvoker is newobj'd every pass through the loop. Curious... can't C# just unroll this version? If not, why not? So while the short hand, inline looks great and probably the nicest to maintain, beware the potential performance costs (unecessary allocations of the delegate) as opposed to this far less elegant, yet more efficient approach:

private void MyBackgroundWorker(object state)
{
 int work = 0;

 MethodInvoker myCallback = new MethodInvoker(
                            delegate()
                            {
                              this.label1.Text = work.ToString();
                            });

 for(work = 0; work < 10000; work++)
 { 
  this.Invoke(myCallback);
 }
}

I guess my next question is for all the real hardcore folks out there that like to get into the JIT'd machine code: Is it unrolled by the JIT? I guess I could just attach the profiler and see how man MethodInvoker's are actually instantiated at runtime, but I'm only running C# Express on this box so I don't have it and AFAIK there's no “official” CLR Profiler for .NET 2.0 yet.

On a related note, I find it really annoying that I have to do new MethodInvoker at all. Why can't I just do:

this.Invoke(delegate()
            {
              this.label1.Text = work.ToString();
            });

I guess in the particular case of Control::Invoke I can understand the need to know exactly what kind of delegate instance to construct because it takes Delegate which is an abstract class. However, even when the type of delegate could be inferred from the method signature it is not. :\