2017-10-23 10 views
-2

아마도 이것은 방법이 async으로 표시 될 때 편집 중에 어떤 일이 발생하는지에 대한 나의 이해 부족 때문입니다. 그러나이 방법은 왜 컴파일됩니까?이 비동기 메서드에 컴파일 오류가없는 이유는 무엇입니까?

public async Task<bool> Test() 
    { 
     return true; 
    } 

여기에서 설명을 찾고 있으므로 어떤 일이 벌어지고 있는지 더 잘 이해할 수 있습니다. Task이 (가) 자동으로 포장됩니까? 이 방법이 허용되는 이유는 무엇입니까? (Task<bool>을 반환하는 메서드 서명을 따르지 않음).

업데이트 :

public void Main() 
    { 
     Input(Test); 
    } 

    public async Task<bool> Test() 
    { 
     return true; 
    } 

    public void Input(Func<Task<bool>> test) 
    { 

    } 

이 시험 방법은 암시 적으로 Task 반환 곳 : 이가 매개 변수도 적용 할 것으로 보인다.

+0

[비동기 및 대기 시간 작동 방식] (https://stackoverflow.com/questions/22349210/how-async-and-await-works)의 가능한 복제본 –

+0

' 비동기식 '방법. 네가 묻고있는거야? –

+0

@ RufusL right 나는 그것을 이해한다. 하지만 이유는 방법 1은 작업을 반환하지 않아도 이해가 안 돼 (해당 서명을 기반으로해야 함) –

답변

4

당신은 상태 머신과 함께, 모든 후 Task<bool>을 반환하지 않습니다,이 방법은 일반적인 비동기 하나에 컴파일 된 코드 here

using System; 
public class C { 
    public async System.Threading.Tasks.Task<bool> M() { 
     return false; 
    } 
} 

의 디 컴파일 된 버전에서 좀 걸릴 수 있습니다.

경고 CS1998이 :이 비동기 방식은 부족 연산자를 '기다리고 없다'와 동 기적으로 를 실행하면 결코 await 당신의 방법에 있기 때문에

public class C 
{ 
    [CompilerGenerated] 
    private sealed class <M>d__0 : IAsyncStateMachine 
    { 
     public int <>1__state; 

     public AsyncTaskMethodBuilder<bool> <>t__builder; 

     public C <>4__this; 

     //called when you awaiting the Task 
     void IAsyncStateMachine.MoveNext() 
     { 
      int num = this.<>1__state; 
      bool result; 
      try 
      { 
       result = false; //the result is set 
      } 
      catch (Exception arg_0C_0) 
      { 
       Exception exception = arg_0C_0; 
       this.<>1__state = -2; 
       this.<>t__builder.SetException(exception); 
       return; 
      } 
      this.<>1__state = -2; 
      this.<>t__builder.SetResult(result); 
     } 

     [DebuggerHidden] 
     void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) 
     { 
     } 
    } 

    [DebuggerStepThrough, AsyncStateMachine(typeof(C.<M>d__0))] 
    public Task<bool> M() 
    { 
     // the state machine instance created 
     C.<M>d__0 <M>d__ = new C.<M>d__0(); 
     <M>d__.<>4__this = this; 
     <M>d__.<>t__builder = AsyncTaskMethodBuilder<bool>.Create(); 
     <M>d__.<>1__state = -1; 
     AsyncTaskMethodBuilder<bool> <>t__builder = <M>d__.<>t__builder; 
     <>t__builder.Start<C.<M>d__0>(ref <M>d__); 
     return <M>d__.<>t__builder.Task; 
    } 
} 

BTW, 컴파일러는, 당신에게 경고를 제공합니다. 'await'연산자를 사용하여 비 차단 API 호출을 기다리거나 'await Task.Run (...)'을 사용하여 백그라운드 스레드에서 CPU 바인딩 작업 을 수행하는 것이 좋습니다.

그리고 당신은 전적으로 옳습니다, 당신은 대신 완성 된 작업을 반환 할 수 있습니다 could be found here 위의 방법을 코딩하는

using System; 
using System.Threading.Tasks; 
public class C { 
    public Task<bool> M() { 
     return Task.FromResult(false); //no need to await here at all 
    } 

}

다른 방법을.

using System; 
using System.Threading.Tasks; 
public class C { 
    public async Task<bool> M() { 
     return false; 
    } 

    public async Task<bool> M2(){ 
     return await Task.FromResult(false); 
    } 

    public Task<bool> M3(){ 
     return Task.FromResult(false); 
    } 
} 

이 내용이 도움이되기를 바랍니다.

+0

나는 당신을 이해하는지 확신하지 못합니다. 작업을 반환합니다. 디 컴파일 된 코드를 참조하십시오. 'return false;를하더라도 실제 상태 머신이 생성되고 태스크가 반환됩니다. 호출자는 그것에 대해 '기다려야'할 수도 있고, 작업을 더 멀리 저장/전달할 수도 있습니다. –

+0

그래서 async 키워드를 추가하여 암시 적으로 작업을 반환합니까? Task.Run (() => true)를 반환하고 비동기 키워드를 제거하면 컴파일 된 코드가 달라질 수 있습니까? –

+0

내 대답의 마지막 링크를 확인하십시오. 당신이'기다리는'모든 상태 기계 직원이 지어지고 초기화됩니다. 윌 모든 성능/메모리 페널티 :) 만약 당신이 방금 완료 작업 ('Task.FromResult') 반환 아무것도 일어나고있다. –