무효 반환과 작업 반환의 차이점은 무엇입니까? Task<MyType>비동기 작업이 완료되면 a를 반환하는 것이 호출자에게

다양한 C # 비동기 CTP 샘플을 보면 반환하는 일부 비동기 함수 void와 제네릭이 아닌 다른 함수를 반환 Task합니다. Task<MyType>비동기 작업이 완료되면 a를 반환하는 것이 호출자에게 데이터를 반환하는 데 유용한 이유를 알 수 있지만 반환 유형이있는 함수는 Task데이터를 반환하지 않습니다. 왜 돌아 오지 void않습니까?



답변

SLaks와 Killercam의 답변은 좋습니다. 컨텍스트를 조금 더 추가하겠다고 생각했습니다.

첫 번째 질문은 본질적으로 어떤 방법을 표시 할 수 있는지에 관한 것 async입니다.

로 표시된 방법은 async반환 할 수 void, Task또는 Task<T>. 그들 사이의 차이점은 무엇입니까?

Task<T>반환 비동기 방법을 기다려온 할 수 있으며, 작업이 완료 될 때 그것은 T.을 신혼합니다

Task반환 비동기 방법을 기다려온 할 수 있으며, 작업이 완료는, 작업의 계속은 실행하도록 예약 할 때.

void반환 비동기 방법을 기다려온 할 수 없다; “화재와 잊어 버리기”방법입니다. 비동기식으로 작동하며 완료 시점을 알 수 없습니다. 이것은 조금 이상합니다. SLaks가 말했듯이 일반적으로 비동기 이벤트 핸들러를 만들 때만 수행합니다. 이벤트가 발생하면 핸들러가 실행됩니다. 이벤트 핸들러는 태스크를 리턴하지 않기 때문에 이벤트 핸들러가 리턴 한 태스크를 “기다릴 것”이 없으며, 수행 한 경우에도 어떤 코드가 태스크를 사용합니까? 일반적으로 컨트롤을 핸들러로 전송하는 것은 사용자 코드가 아닙니다.

의견에서 두 번째 질문은 본질적으로 await먹을 수있는 것에 관한 것입니다 .

어떤 종류의 방법을 사용할 수 await있습니까? 무효 반환 방법을 사용할 수 await있습니까?

아니요, 무효 반환 방법을 기다릴 수 없습니다. 컴파일러는 await M()에 대한 호출로 변환 되며 M().GetAwaiter(), 여기서 GetAwaiter인스턴스 메소드 또는 확장 메소드 일 수 있습니다. 기다리는 값은 기다리는 사람을 얻을 수있는 값이어야합니다. 분명히 void-returning 방법은 당신이 기다리는 사람을 얻을 수있는 가치를 생산하지 않습니다.

Task반환 방법은 대기 가능한 값을 생성 할 수 있습니다. 우리는 제 3자가 Task기다릴 수있는 유사한 객체 의 자체 구현을 만들고 싶어 할 것이며, 당신은 그것들을 기다릴 수있을 것입니다. 그러나 선언 허용되지 않습니다 async반환 아무것도하지만, 방법 void, Task또는 Task<T>.

(업데이트 : 마지막 문장은 C #의 미래 버전에 의해 위조 될 수 있습니다. 비동기 메서드에 대한 작업 유형 이외의 반환 유형을 허용하는 제안이 있습니다.)

(업데이트 : 위에서 언급 한 기능으로 인해 C # 7이되었습니다.)


답변

발신자가 작업을 기다리거나 연속을 추가하려는 경우.

사실, 이벤트 핸들러를 작성하여 리턴 void수없는 경우 리턴해야하는 유일한 이유가 있습니다Task .


답변

반환하는 메서드 TaskTask<T>구성 가능- 메서드 await내에서 async메서드 를 사용할 수 있음을 의미합니다 .

async리턴 void하는 메소드 는 합성 할 수 없지만 두 가지 중요한 특성이 있습니다.

  1. 이벤트 핸들러로 사용할 수 있습니다.
  2. “최상위”비동기 작업을 나타냅니다.

두 번째 요점은 뛰어난 비동기 작업 를 유지하는 컨텍스트를 처리 할 때 중요 합니다.

ASP.NET 컨텍스트는 그러한 컨텍스트 중 하나입니다. 비동기 Task메소드에서 기다리지 않고 비동기 메소드 를 사용 void하면 ASP.NET 요청이 너무 빨리 완료됩니다.

또 다른 맥락은 AsyncContext내가 단위 테스트를 위해 작성한 것입니다 ( 여기에서 사용 가능 )- AsyncContext.Run메소드는 미해결 작업 수를 추적하고 0 일 때 반환합니다.


답변

유형 Task<T>은 태스크 병렬 라이브러리 (TPL)의 주력 유형이며, ” T미래 에 유형 결과를 생성 할 일부 작업 / 작업”의 개념을 나타냅니다 . “미래에 완료되지만 결과를 반환하지 않는 작업”이라는 개념은 일반적인 작업 유형이 아닙니다.

정확하게 결과 유형 T이 어떻게 만들어 질 것인지는 특정 작업의 구현 세부 사항입니다. 작업은 로컬 시스템의 다른 프로세스, 다른 스레드 등으로 팜핑 될 수 있습니다. TPL 태스크는 일반적으로 현재 프로세스의 스레드 풀에서 작업자 스레드로 팜 아웃되지만 구현 세부 사항은 Task<T>유형의 기본이 아닙니다 . 오히려은 Task<T>을 생성하는 대기 시간이 긴 작업을 나타낼 수 있습니다 T.

위의 의견을 바탕으로 :

await표현식은 “이 표현식을 평가하여 나중에 결과를 생성 할 작업을 나타내는 오브젝트를 얻습니다. 해당 태스크의 지속과 연관된 콜백으로 현재 메소드의 나머지를 등록하십시오. 일단 태스크가 생성되고 콜백되면 가입하면 즉시 발신자에게 제어권을 반환합니다. ” 이것은 일반적인 메소드 호출과는 대조적입니다. 즉, “하고있는 일을 기억하고, 완료 될 때까지이 메소드를 실행 한 다음 중단 된 위치를 선택하여 메소드의 결과를 알고 있습니다”라는 의미입니다.


편집 : 2011 년 10 월 MSDN Magazine에서 Eric Lippert의 기사를 인용해야합니다.

더 많은 정보와 화이트 페이지를 보려면 여기를 참조 하십시오 .

이것이 도움이되기를 바랍니다.


답변