5

我想为多线程应用程序生成 IL。作为第一步,我编写了一个简单的应用程序并使用 ILSpy 检查生成的 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 吗?

4

2 回答 2

6

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

于 2011-07-23T16:13:58.540 回答
4

IL 中没有“匿名方法”这样的概念。C# 编译器所做的是创建具有难以描述的名称 ( <Main>b__0) 和静态字段的普通方法,以缓存方法的委托 ( CS$<>9__CachedAnonymousMethodDelegate1)。

你应该做什么取决于你想做什么。如果您不想缓存委托,则不必这样做,您可以创建它,它会在一定程度上简化您的代码。

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

于 2011-07-23T16:20:17.953 回答