Any difference between “await Task.Run(); return;” and “return Task.Run()”?

后端 未结 4 1122
日久生厌
日久生厌 2020-11-22 01:59

Is there any conceptual difference between the following two pieces of code:

async Task TestAsync() 
{
    await Task.Run(() => DoSomeWork());
}
         


        
4条回答
  •  北恋
    北恋 (楼主)
    2020-11-22 02:58

    1. The first method does not even compile.

      Since 'Program.TestAsync()' is an async method that returns 'Task', a return keyword must not be followed by an object expression. Did you intend to return 'Task'?

      It has to be

      async Task TestAsync()
      {
          await Task.Run(() => DoSomeWork());
      }
      
    2. There is major conceptual difference between these two. The first one is asynchronous, the second one is not. Read Async Performance: Understanding the Costs of Async and Await to get a little more about internals of async/await.

    3. They do generate different code.

      .method private hidebysig 
          instance class [mscorlib]System.Threading.Tasks.Task TestAsync () cil managed 
      {
          .custom instance void [mscorlib]System.Runtime.CompilerServices.AsyncStateMachineAttribute::.ctor(class [mscorlib]System.Type) = (
              01 00 25 53 4f 54 65 73 74 50 72 6f 6a 65 63 74
              2e 50 72 6f 67 72 61 6d 2b 3c 54 65 73 74 41 73
              79 6e 63 3e 64 5f 5f 31 00 00
          )
          .custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = (
              01 00 00 00
          )
          // Method begins at RVA 0x216c
          // Code size 62 (0x3e)
          .maxstack 2
          .locals init (
              [0] valuetype SOTestProject.Program/'d__1',
              [1] class [mscorlib]System.Threading.Tasks.Task,
              [2] valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder
          )
      
          IL_0000: ldloca.s 0
          IL_0002: ldarg.0
          IL_0003: stfld class SOTestProject.Program SOTestProject.Program/'d__1'::'<>4__this'
          IL_0008: ldloca.s 0
          IL_000a: call valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Create()
          IL_000f: stfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder SOTestProject.Program/'d__1'::'<>t__builder'
          IL_0014: ldloca.s 0
          IL_0016: ldc.i4.m1
          IL_0017: stfld int32 SOTestProject.Program/'d__1'::'<>1__state'
          IL_001c: ldloca.s 0
          IL_001e: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder SOTestProject.Program/'d__1'::'<>t__builder'
          IL_0023: stloc.2
          IL_0024: ldloca.s 2
          IL_0026: ldloca.s 0
          IL_0028: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Startd__1'>(!!0&)
          IL_002d: ldloca.s 0
          IL_002f: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder SOTestProject.Program/'d__1'::'<>t__builder'
          IL_0034: call instance class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::get_Task()
          IL_0039: stloc.1
          IL_003a: br.s IL_003c
      
          IL_003c: ldloc.1
          IL_003d: ret
      } // end of method Program::TestAsync
      

      and

      .method private hidebysig 
          instance class [mscorlib]System.Threading.Tasks.Task TestAsync2 () cil managed 
      {
          // Method begins at RVA 0x21d8
          // Code size 23 (0x17)
          .maxstack 2
          .locals init (
              [0] class [mscorlib]System.Threading.Tasks.Task CS$1$0000
          )
      
          IL_0000: nop
          IL_0001: ldarg.0
          IL_0002: ldftn instance class [mscorlib]System.Threading.Tasks.Task SOTestProject.Program::'b__4'()
          IL_0008: newobj instance void class [mscorlib]System.Func`1::.ctor(object, native int)
          IL_000d: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::Run(class [mscorlib]System.Func`1)
          IL_0012: stloc.0
          IL_0013: br.s IL_0015
      
          IL_0015: ldloc.0
          IL_0016: ret
      } // end of method Program::TestAsync2
      

提交回复
热议问题