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デリゲートタイプ})を呼び出し、それを目的のデリゲートタイプ(おそらくThreadStart)にキャストし、(型指定された)デリゲートインスタンスを任意の場所に格納します。

于 2011-07-23T16:13:58.540 に答える
4

これは、ILの「匿名メソッド」のような概念ではありません。<Main>b__0C#コンパイラが行うことは、言いようのない名前( )とメソッドへのデリゲートをキャッシュする静的フィールド()を使用して通常のメソッドを作成することCS$<>9__CachedAnonymousMethodDelegate1です。

何をすべきかは、何をしたいかによって異なります。デリゲートをキャッシュしたくない場合は、キャッシュする必要はありません。キャッシュを作成すると、コードがいくらか単純化されます。

匿名メソッドを通常のメソッドに変換し、ILSpyでそれを見ると、簡略化されたIL(なしldsfld)が表示され、それを生成できます。

于 2011-07-23T16:20:17.953 に答える