2011-07-23 52 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