2011-07-23 51 views
5

我想为多线程应用程序生成IL。作为第一步 我写了一个简单的应用程序,并使用ILSpy检查,生成了IL。为匿名方法生成IL

public class ThreadTesting 
{ 
    public static void Main() 
    { 
     Thread thread = new Thread(() => Print("Hello from t!")); 
     thread.Start(); 
    } 

    public static void Print(string message) 
    { 
     Console.WriteLine(message); 
    } 
} 
.method public hidebysig static 
    void Main() cil managed 
{ 
    // Method begins at RVA 0x2060 
    // Code size 46 (0x2e) 
    .maxstack 3 
    .entrypoint 
    .locals init (
     [0] class [mscorlib]System.Threading.Thread 
    ) 

    IL_0000: nop 
    IL_0001: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1' 
    IL_0006: brtrue.s IL_001b 

    IL_0008: ldnull 
    IL_0009: ldftn void ThreadTesting::'<Main>b__0'() 
    IL_000f: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, native int) 
    IL_0014: stsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1' 
    IL_0019: br.s IL_001b 

    IL_001b: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1' 
    IL_0020: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) 
    IL_0025: stloc.0 
    IL_0026: ldloc.0 
    IL_0027: callvirt instance void [mscorlib]System.Threading.Thread::Start() 
    IL_002c: nop 
    IL_002d: ret 
} // end of method ThreadTesting::Main 

我能够生成最使用System.Reflection.Emit 命名空间上述IL代码。

不幸我不知道如何使用System.Reflection.Emit在IL代码后生成 。

IL_0001: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1' 

所以能有人帮助我弄清楚 如何产生IL匿名方法?

回答

6

IL只是编译器缓存委托实例的方式 - 它不是方法本身的一部分。如果您正在使用DynamicMethod(您可能应该是),那么只需调用CreateDelegate({您的委托类型}),将其转换为您所需的委托类型(可能是ThreadStart),然后将(类型)委托实例存储到任何地方。

4

IL中没有“匿名方法”这样的概念。 C#编译器所做的是使用不可知名称(<Main>b__0)和用于将委托缓存到方法(CS$<>9__CachedAnonymousMethodDelegate1)的静态字段来创建常规方法。

你应该做什么取决于你想要做什么。如果你不想缓存委托,你不需要,你可以创建它,它会简化你的代码。

如果您将匿名方法转换为普通方法,并在ILSpy中查看,您将看到简化的IL(无ldsfld),您可以生成该方法。

+0

缓存可能是更重要的使用排放 - 但如果它永远不会被重用,那么确实没有理由存储它。 –

+0

@Marc,我假设匿名方法和使用它的方法都是使用emit生成的。在这种情况下,我认为缓存没有什么帮助,因为它只保存一个对委托构造函数的调用。如果不缓存意味着再次生成整个方法,那么当然你是对的。 – svick