2016-12-13 12 views
-1

async - awaitを使用して作成された状態マシンを理解しようとしています。私はC#のコードのシンプルな作品に疑似コードに関して、MILのIAsyncStateMachineのMoveNextは何をしますか?

using System; 
using System.Net; 
using System.Threading.Tasks; 
public class C 
{ 
    public static async Task<string> GetGoogleDotComHtml() 
    { 
     using(WebClient wc = new WebClient()) 
     { 
      var task = new Task<string>(() => wc.DownloadString("http://google.com")); 
      string html = await task; 
      return html; 
     } 
    } 
    public void M() 
    { 
     string googleHomepage = GetGoogleDotComHtml().Result; 
     Console.WriteLine(googleHomepage); 
    } 
} 

を取ると私は理解して欲しい

.class private auto ansi '<Module>' 
{ 
} // end of class <Module> 

.class public auto ansi beforefieldinit C 
    extends [mscorlib]System.Object 
{ 
    // Nested Types 
    .class nested private auto ansi sealed beforefieldinit '<>c__DisplayClass0_0' 
     extends [mscorlib]System.Object 
    { 
     .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
      01 00 00 00 
     ) 
     // Fields 
     .field public class [System]System.Net.WebClient wc 

     // Methods 
     .method public hidebysig specialname rtspecialname 
      instance void .ctor() cil managed 
     { 
      // Method begins at RVA 0x20b0 
      // Code size 8 (0x8) 
      .maxstack 8 

      IL_0000: ldarg.0    // Load argument 0 onto the stack 
      IL_0001: call instance void [mscorlib]System.Object::.ctor() // Call method indicated on the stack with arguments 
      IL_0006: nop     // Do nothing (No operation) 
      IL_0007: ret     // Return from method, possibly with a value 
     } // end of method '<>c__DisplayClass0_0'::.ctor 

     .method assembly hidebysig 
      instance string '<GetGoogleDotComHtml>b__0'() cil managed 
     { 
      // Method begins at RVA 0x20b9 
      // Code size 17 (0x11) 
      .maxstack 8 

      IL_0000: ldarg.0    // Load argument 0 onto the stack 
      IL_0001: ldfld class [System]System.Net.WebClient C/'<>c__DisplayClass0_0'::wc // Push the value of field of object (or value type) obj, onto the stack 
      IL_0006: ldstr "http://google.com" // Push a string object for the literal string 
      IL_000b: callvirt instance string [System]System.Net.WebClient::DownloadString(string) // Call a method associated with an object 
      IL_0010: ret     // Return from method, possibly with a value 
     } // end of method '<>c__DisplayClass0_0'::'<GetGoogleDotComHtml>b__0' 

    } // end of class <>c__DisplayClass0_0 

    .class nested private auto ansi sealed beforefieldinit '<GetGoogleDotComHtml>d__0' 
     extends [mscorlib]System.Object 
     implements [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine 
    { 
     .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
      01 00 00 00 
     ) 
     // Fields 
     .field public int32 '<>1__state' 
     .field public valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> '<>t__builder' 
     .field private class C/'<>c__DisplayClass0_0' '<>8__1' 
     .field private class [mscorlib]System.Threading.Tasks.Task`1<string> '<task>5__2' 
     .field private string '<html>5__3' 
     .field private string '<>s__4' 
     .field private valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<string> '<>u__1' 

     // Methods 
     .method public hidebysig specialname rtspecialname 
      instance void .ctor() cil managed 
     { 
      // Method begins at RVA 0x20b0 
      // Code size 8 (0x8) 
      .maxstack 8 

      IL_0000: ldarg.0    // Load argument 0 onto the stack 
      IL_0001: call instance void [mscorlib]System.Object::.ctor() // Call method indicated on the stack with arguments 
      IL_0006: nop     // Do nothing (No operation) 
      IL_0007: ret     // Return from method, possibly with a value 
     } // end of method '<GetGoogleDotComHtml>d__0'::.ctor 

     .method private final hidebysig newslot virtual 
      instance void MoveNext() cil managed 
     { 
      .override method instance void [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext() 
      // Method begins at RVA 0x20cc 
      // Code size 302 (0x12e) 
      .maxstack 3 
      .locals init (
       [0] int32, 
       [1] string, 
       [2] valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<string>, 
       [3] string, 
       [4] class C/'<GetGoogleDotComHtml>d__0', 
       [5] class [mscorlib]System.Exception 
      ) 

      IL_0000: ldarg.0    // Load argument 0 onto the stack 
      IL_0001: ldfld int32 C/'<GetGoogleDotComHtml>d__0'::'<>1__state' // Push the value of field of object (or value type) obj, onto the stack 
      IL_0006: stloc.0    // Pop a value from stack into local variable 0 
      IL_0007: ldloc.0    // Load local variable 0 onto stack 
      IL_0008: brfalse.s IL_000c // Branch to target if value is zero (false), short form 
      IL_000a: br.s IL_000e   // Branch to target, short form 
      IL_000c: br.s IL_002a   // Branch to target, short form 
      IL_000e: nop     // Do nothing (No operation) 
      IL_000f: ldarg.0    // Load argument 0 onto the stack 
      IL_0010: newobj instance void C/'<>c__DisplayClass0_0'::.ctor() // Allocate an uninitialized object or value type and call ctor 
      IL_0015: stfld class C/'<>c__DisplayClass0_0' C/'<GetGoogleDotComHtml>d__0'::'<>8__1' // Replace the value of field of the object obj with value 
      IL_001a: ldarg.0    // Load argument 0 onto the stack 
      IL_001b: ldfld class C/'<>c__DisplayClass0_0' C/'<GetGoogleDotComHtml>d__0'::'<>8__1' // Push the value of field of object (or value type) obj, onto the stack 
      IL_0020: newobj instance void [System]System.Net.WebClient::.ctor() // Allocate an uninitialized object or value type and call ctor 
      IL_0025: stfld class [System]System.Net.WebClient C/'<>c__DisplayClass0_0'::wc // Replace the value of field of the object obj with value 
      IL_002a: nop     // Do nothing (No operation) 
      IL_002b: ldloc.0    // Load local variable 0 onto stack 
      IL_002c: brfalse.s IL_0030 // Branch to target if value is zero (false), short form 
      IL_002e: br.s IL_0032   // Branch to target, short form 
      IL_0030: br.s IL_008c   // Branch to target, short form 
      IL_0032: nop     // Do nothing (No operation) 
      IL_0033: ldarg.0    // Load argument 0 onto the stack 
      IL_0034: ldarg.0    // Load argument 0 onto the stack 
      IL_0035: ldfld class C/'<>c__DisplayClass0_0' C/'<GetGoogleDotComHtml>d__0'::'<>8__1' // Push the value of field of object (or value type) obj, onto the stack 
      IL_003a: ldftn instance string C/'<>c__DisplayClass0_0'::'<GetGoogleDotComHtml>b__0'() // Push a pointer to a method referenced by method, on the stack 
      IL_0040: newobj instance void class [mscorlib]System.Func`1<string>::.ctor(object, native int) // Allocate an uninitialized object or value type and call ctor 
      IL_0045: newobj instance void class [mscorlib]System.Threading.Tasks.Task`1<string>::.ctor(class [mscorlib]System.Func`1<!0>) // Allocate an uninitialized object or value type and call ctor 
      IL_004a: stfld class [mscorlib]System.Threading.Tasks.Task`1<string> C/'<GetGoogleDotComHtml>d__0'::'<task>5__2' // Replace the value of field of the object obj with value 
      IL_004f: ldarg.0    // Load argument 0 onto the stack 
      IL_0050: ldfld class [mscorlib]System.Threading.Tasks.Task`1<string> C/'<GetGoogleDotComHtml>d__0'::'<task>5__2' // Push the value of field of object (or value type) obj, onto the stack 
      IL_0055: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<!0> class [mscorlib]System.Threading.Tasks.Task`1<string>::GetAwaiter() // Call a method associated with an object 
      IL_005a: stloc.2    // Pop a value from stack into local variable 2 
      IL_005b: ldloca.s 2   // Load address of local variable with index indx, short form 
      IL_005d: call instance bool valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<string>::get_IsCompleted() // Call method indicated on the stack with arguments 
      IL_0062: brtrue.s IL_00a8  // Branch to target if value is non-zero (true), short form 
      IL_0064: ldarg.0    // Load argument 0 onto the stack 
      IL_0065: ldc.i4.0    // Push 0 onto the stack as int32 
      IL_0066: dup     // Duplicate the value on the top of the stack 
      IL_0067: stloc.0    // Pop a value from stack into local variable 0 
      IL_0068: stfld int32 C/'<GetGoogleDotComHtml>d__0'::'<>1__state' // Replace the value of field of the object obj with value 
      IL_006d: ldarg.0    // Load argument 0 onto the stack 
      IL_006e: ldloc.2    // Load local variable 2 onto stack 
      IL_006f: stfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<string> C/'<GetGoogleDotComHtml>d__0'::'<>u__1' // Replace the value of field of the object obj with value 
      IL_0074: ldarg.0    // Load argument 0 onto the stack 
      IL_0075: stloc.s 4   // Pop a value from stack into local variable indx, short form 
      IL_0077: ldarg.0    // Load argument 0 onto the stack 
      IL_0078: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> C/'<GetGoogleDotComHtml>d__0'::'<>t__builder' // Push the address of field of object obj on the stack 
      IL_007d: ldloca.s 2   // Load address of local variable with index indx, short form 
      IL_007f: ldloca.s 4   // Load address of local variable with index indx, short form 
      IL_0081: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::AwaitUnsafeOnCompleted<valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<string>, class C/'<GetGoogleDotComHtml>d__0'>(!!0&, !!1&) // Call method indicated on the stack with arguments 
      IL_0086: nop     // Do nothing (No operation) 
      IL_0087: leave IL_012d  // Exit a protected region of code 
      IL_008c: ldarg.0    // Load argument 0 onto the stack 
      IL_008d: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<string> C/'<GetGoogleDotComHtml>d__0'::'<>u__1' // Push the value of field of object (or value type) obj, onto the stack 
      IL_0092: stloc.2    // Pop a value from stack into local variable 2 
      IL_0093: ldarg.0    // Load argument 0 onto the stack 
      IL_0094: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<string> C/'<GetGoogleDotComHtml>d__0'::'<>u__1' // Push the address of field of object obj on the stack 
      IL_0099: initobj valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<string> // Initialize the value at address dest 
      IL_009f: ldarg.0    // Load argument 0 onto the stack 
      IL_00a0: ldc.i4.m1   // Push -1 onto the stack as int32 
      IL_00a1: dup     // Duplicate the value on the top of the stack 
      IL_00a2: stloc.0    // Pop a value from stack into local variable 0 
      IL_00a3: stfld int32 C/'<GetGoogleDotComHtml>d__0'::'<>1__state' // Replace the value of field of the object obj with value 
      IL_00a8: ldloca.s 2   // Load address of local variable with index indx, short form 
      IL_00aa: call instance !0 valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<string>::GetResult() // Call method indicated on the stack with arguments 
      IL_00af: stloc.3    // Pop a value from stack into local variable 3 
      IL_00b0: ldloca.s 2   // Load address of local variable with index indx, short form 
      IL_00b2: initobj valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<string> // Initialize the value at address dest 
      IL_00b8: ldarg.0    // Load argument 0 onto the stack 
      IL_00b9: ldloc.3    // Load local variable 3 onto stack 
      IL_00ba: stfld string C/'<GetGoogleDotComHtml>d__0'::'<>s__4' // Replace the value of field of the object obj with value 
      IL_00bf: ldarg.0    // Load argument 0 onto the stack 
      IL_00c0: ldarg.0    // Load argument 0 onto the stack 
      IL_00c1: ldfld string C/'<GetGoogleDotComHtml>d__0'::'<>s__4' // Push the value of field of object (or value type) obj, onto the stack 
      IL_00c6: stfld string C/'<GetGoogleDotComHtml>d__0'::'<html>5__3' // Replace the value of field of the object obj with value 
      IL_00cb: ldarg.0    // Load argument 0 onto the stack 
      IL_00cc: ldnull    // Push a null reference on the stack 
      IL_00cd: stfld string C/'<GetGoogleDotComHtml>d__0'::'<>s__4' // Replace the value of field of the object obj with value 
      IL_00d2: ldarg.0    // Load argument 0 onto the stack 
      IL_00d3: ldfld string C/'<GetGoogleDotComHtml>d__0'::'<html>5__3' // Push the value of field of object (or value type) obj, onto the stack 
      IL_00d8: stloc.1    // Pop a value from stack into local variable 1 
      IL_00d9: leave.s IL_0118  // Exit a protected region of code, short form 
      IL_00db: ldloc.0    // Load local variable 0 onto stack 
      IL_00dc: ldc.i4.0    // Push 0 onto the stack as int32 
      IL_00dd: bge.s IL_00fd  // Branch to target if greater than or equal to, short form 
      IL_00df: ldarg.0    // Load argument 0 onto the stack 
      IL_00e0: ldfld class C/'<>c__DisplayClass0_0' C/'<GetGoogleDotComHtml>d__0'::'<>8__1' // Push the value of field of object (or value type) obj, onto the stack 
      IL_00e5: ldfld class [System]System.Net.WebClient C/'<>c__DisplayClass0_0'::wc // Push the value of field of object (or value type) obj, onto the stack 
      IL_00ea: brfalse.s IL_00fd // Branch to target if value is zero (false), short form 
      IL_00ec: ldarg.0    // Load argument 0 onto the stack 
      IL_00ed: ldfld class C/'<>c__DisplayClass0_0' C/'<GetGoogleDotComHtml>d__0'::'<>8__1' // Push the value of field of object (or value type) obj, onto the stack 
      IL_00f2: ldfld class [System]System.Net.WebClient C/'<>c__DisplayClass0_0'::wc // Push the value of field of object (or value type) obj, onto the stack 
      IL_00f7: callvirt instance void [mscorlib]System.IDisposable::Dispose() // Call a method associated with an object 
      IL_00fc: nop     // Do nothing (No operation) 
      IL_00fd: endfinally   // End finally clause of an exception block 
      IL_00fe: stloc.s 5   // Pop a value from stack into local variable indx, short form 
      IL_0100: ldarg.0    // Load argument 0 onto the stack 
      IL_0101: ldc.i4.s -2   // Push num onto the stack as int32, short form 
      IL_0103: stfld int32 C/'<GetGoogleDotComHtml>d__0'::'<>1__state' // Replace the value of field of the object obj with value 
      IL_0108: ldarg.0    // Load argument 0 onto the stack 
      IL_0109: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> C/'<GetGoogleDotComHtml>d__0'::'<>t__builder' // Push the address of field of object obj on the stack 
      IL_010e: ldloc.s 5   // Load local variable of index indx onto stack, short form 
      IL_0110: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::SetException(class [mscorlib]System.Exception) // Call method indicated on the stack with arguments 
      IL_0115: nop     // Do nothing (No operation) 
      IL_0116: leave.s IL_012d  // Exit a protected region of code, short form 
      IL_0118: ldarg.0    // Load argument 0 onto the stack 
      IL_0119: ldc.i4.s -2   // Push num onto the stack as int32, short form 
      IL_011b: stfld int32 C/'<GetGoogleDotComHtml>d__0'::'<>1__state' // Replace the value of field of the object obj with value 
      IL_0120: ldarg.0    // Load argument 0 onto the stack 
      IL_0121: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> C/'<GetGoogleDotComHtml>d__0'::'<>t__builder' // Push the address of field of object obj on the stack 
      IL_0126: ldloc.1    // Load local variable 1 onto stack 
      IL_0127: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::SetResult(!0) // Call method indicated on the stack with arguments 
      IL_012c: nop     // Do nothing (No operation) 
      IL_012d: ret     // Return from method, possibly with a value 

      Try IL_002b-IL_00db Finally IL_00db-IL_00fe 
      Try IL_0007-IL_00fe Catch class [mscorlib]System.Exception IL_00fe-IL_0118 
     } // end of method '<GetGoogleDotComHtml>d__0'::MoveNext 

     .method private final hidebysig newslot virtual 
      instance void SetStateMachine (
       class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine stateMachine 
      ) cil managed 
     { 
      .custom instance void [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::.ctor() = (
       01 00 00 00 
      ) 
      .override method instance void [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine::SetStateMachine(class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine) 
      // Method begins at RVA 0x2224 
      // Code size 1 (0x1) 
      .maxstack 8 

      IL_0000: ret     // Return from method, possibly with a value 
     } // end of method '<GetGoogleDotComHtml>d__0'::SetStateMachine 

    } // end of class <GetGoogleDotComHtml>d__0 


    // Methods 
    .method public hidebysig static 
     class [mscorlib]System.Threading.Tasks.Task`1<string> GetGoogleDotComHtml() cil managed 
    { 
     .custom instance void [mscorlib]System.Runtime.CompilerServices.AsyncStateMachineAttribute::.ctor(class [mscorlib]System.Type) = (
      01 00 1b 43 2b 3c 47 65 74 47 6f 6f 67 6c 65 44 
      6f 74 43 6f 6d 48 74 6d 6c 3e 64 5f 5f 30 00 00 
     ) 
     .custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = (
      01 00 00 00 
     ) 
     // Method begins at RVA 0x2050 
     // Code size 52 (0x34) 
     .maxstack 2 
     .locals init (
      [0] class C/'<GetGoogleDotComHtml>d__0', 
      [1] valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> 
     ) 

     IL_0000: newobj instance void C/'<GetGoogleDotComHtml>d__0'::.ctor() // Allocate an uninitialized object or value type and call ctor 
     IL_0005: stloc.0    // Pop a value from stack into local variable 0 
     IL_0006: ldloc.0    // Load local variable 0 onto stack 
     IL_0007: call valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<!0> valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::Create() // Call method indicated on the stack with arguments 
     IL_000c: stfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> C/'<GetGoogleDotComHtml>d__0'::'<>t__builder' // Replace the value of field of the object obj with value 
     IL_0011: ldloc.0    // Load local variable 0 onto stack 
     IL_0012: ldc.i4.m1   // Push -1 onto the stack as int32 
     IL_0013: stfld int32 C/'<GetGoogleDotComHtml>d__0'::'<>1__state' // Replace the value of field of the object obj with value 
     IL_0018: ldloc.0    // Load local variable 0 onto stack 
     IL_0019: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> C/'<GetGoogleDotComHtml>d__0'::'<>t__builder' // Push the value of field of object (or value type) obj, onto the stack 
     IL_001e: stloc.1    // Pop a value from stack into local variable 1 
     IL_001f: ldloca.s 1   // Load address of local variable with index indx, short form 
     IL_0021: ldloca.s 0   // Load address of local variable with index indx, short form 
     IL_0023: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::Start<class C/'<GetGoogleDotComHtml>d__0'>(!!0&) // Call method indicated on the stack with arguments 
     IL_0028: ldloc.0    // Load local variable 0 onto stack 
     IL_0029: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> C/'<GetGoogleDotComHtml>d__0'::'<>t__builder' // Push the address of field of object obj on the stack 
     IL_002e: call instance class [mscorlib]System.Threading.Tasks.Task`1<!0> valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::get_Task() // Call method indicated on the stack with arguments 
     IL_0033: ret     // Return from method, possibly with a value 
    } // end of method C::GetGoogleDotComHtml 

    .method public hidebysig 
     instance void M() cil managed 
    { 
     // Method begins at RVA 0x2090 
     // Code size 20 (0x14) 
     .maxstack 1 
     .locals init (
      [0] string 
     ) 

     IL_0000: nop     // Do nothing (No operation) 
     IL_0001: call class [mscorlib]System.Threading.Tasks.Task`1<string> C::GetGoogleDotComHtml() // Call method indicated on the stack with arguments 
     IL_0006: callvirt instance !0 class [mscorlib]System.Threading.Tasks.Task`1<string>::get_Result() // Call a method associated with an object 
     IL_000b: stloc.0    // Pop a value from stack into local variable 0 
     IL_000c: ldloc.0    // Load local variable 0 onto stack 
     IL_000d: call void [mscorlib]System.Console::WriteLine(string) // Call method indicated on the stack with arguments 
     IL_0012: nop     // Do nothing (No operation) 
     IL_0013: ret     // Return from method, possibly with a value 
    } // end of method C::M 

    .method public hidebysig specialname rtspecialname 
     instance void .ctor() cil managed 
    { 
     // Method begins at RVA 0x20b0 
     // Code size 8 (0x8) 
     .maxstack 8 

     IL_0000: ldarg.0    // Load argument 0 onto the stack 
     IL_0001: call instance void [mscorlib]System.Object::.ctor() // Call method indicated on the stack with arguments 
     IL_0006: nop     // Do nothing (No operation) 
     IL_0007: ret     // Return from method, possibly with a value 
    } // end of method C::.ctor 

} // end of class C 

の逆コンパイルILを取得するにはロスリンを使用MoveNext()方法がどのように動作するかです。基本的なアクションが完了したかどうかを確認するためにチェックが行われる場所です。誰かを擬似コードに変換できますか?

+2

ILの代わりにC#にデコンパイルしないのはなぜですか? – ColinM

答えて

0

MoveNext「このメソッドの次の部分を実行する」という意味です。それはメソッドがどこで中断したかを示す "状態"を持っています。詳細については、Jon Skeet's blogを参照してください。

関連する問題