void 반환과 작업 반환의 차이점은 무엇입니까?
다양한 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
.
반환하는 메서드 Task
와 Task<T>
구성 가능- 메서드 await
내에서 async
메서드 를 사용할 수 있음을 의미합니다 .
async
리턴 void
하는 메소드 는 컴포지션 할 수 없지만 두 가지 중요한 특성이 있습니다.
- 이벤트 핸들러로 사용할 수 있습니다.
- "최상위"비동기 작업을 나타냅니다.
두 번째 요점은 뛰어난 비동기 작업 수 를 유지하는 컨텍스트를 처리 할 때 중요 합니다.
ASP.NET 컨텍스트는 그러한 컨텍스트 중 하나입니다. 비동기 Task
메소드에서 기다리지 않고 비동기 메소드 를 사용 void
하면 ASP.NET 요청이 너무 일찍 완료됩니다.
또 다른 맥락은 AsyncContext
단위 테스트를 위해 작성한 것입니다 ( 여기에서 사용 가능 ).이 AsyncContext.Run
방법은 미해결 작업 수를 추적하고 0 일 때 반환합니다.
유형 Task<T>
은 태스크 병렬 라이브러리 (TPL)의 주력 유형이며 " T
미래 에 유형 결과를 생성 할 일부 작업 / 작업"의 개념을 나타냅니다 . "미래에 완료되지만 결과를 반환하지 않는 작업"이라는 개념은 일반적인 작업 유형이 아닙니다.
형식의 결과가 어떻게 만들어 질지 정확하게 T
그리고 특정 작업의 구현 세부 사항입니다. 작업은 로컬 시스템의 다른 프로세스, 다른 스레드 등으로 팜핑 될 수 있습니다. TPL 태스크는 일반적으로 현재 프로세스의 스레드 풀에서 작업자 스레드로 팜 아웃되지만 구현 세부 사항은 Task<T>
유형의 기본이 아닙니다 . 오히려은 Task<T>
을 생성하는 대기 시간이 긴 작업을 나타낼 수 있습니다 T
.
위의 의견을 바탕으로 :
The await
expression means "evaluate this expression to obtain an object representing work that will in future produce a result. Sign up the remainder of the current method as the call back associated with the continuation of that task. Once that task is produced and the call back is signed up, immediately return control to my caller". This is opposed/in contrast to a regular method call, which means "remember what you're doing, run this method until it is completely finished and then pick up where you left off, now knowing the result of the method".
Edit: I should cite Eric Lippert's article in October 2011 MSDN Magazine as this was a great help to me in understanding this stuff in the first place.
For loads more infromation and whitepages see here.
I hope this is of some help.
'IT story' 카테고리의 다른 글
Windows 7에서도 WPF 응용 프로그램을 메트로 스타일로 보이게합니까? (0) | 2020.07.14 |
---|---|
SVG를 ReactJS에 포함 (0) | 2020.07.14 |
Android에서 뷰를 표시하지 않고 비트 맵으로 변환 하시겠습니까? (0) | 2020.07.14 |
href 속성없이 (앵커 태그) (0) | 2020.07.14 |
핸들 바를 통한 변수 전달 (0) | 2020.07.14 |