2017-10-10 2 views
3

내가 이와 같은 방법을 말해봐 :비동기 함수에서 왜 내가 기다려야합니까?

private async Task SomeMethod() 
{ 
    await DoSomethingAsync(); 
    await DoSomethingElseAsync(); 
    return; 
} 

DoSomethingElseAsync 당신이 할 수있을 것 같은 Task이는 것 같다 반환을 감안할 때 :

private async Task SomeMethod() 
{ 
    await DoSomethingAsync(); 
    return DoSomethingElseAsync(); 
} 

을하지만, 컴파일러는 이것에 대해 불평 :

'SomeMethod'이 (가) 'Task'을 반환하는 비동기 메소드이므로 return 키워드는 객체 표현이 뒤따라야합니다. 'Task<T>'을 반환 하시겠습니까?

왜 그렇습니까?

+4

@YvetteColomb *이 질문과 정확히 일치하지 않습니다. 영업 사원은 기다릴 시간을 묻지 않습니다. 이 질문에'왜 내가 태스크를 반환 할 수 없습니까? '라고 묻습니다. –

+0

@YvetteColomb 이것은 중복되지 않습니다. 당신이 말하는 질문은 기다리는 시간을 사용하는 것입니다.이 두 번째 방법은 왜 기다리는 쓰지 않고 돌아갈 수 없는지 묻습니다. 이 두 가지를 다른 것으로 식별하는 것은 매우 분명합니다. –

+4

첫 번째'DoSomethingAsync();'가 완료되기 전에 메서드가 이미 호출자에게 반환되었습니다 (결국 비동기 메서드입니다). 따라서'await' 후에 특정 값을 반환 할 수있는 방법이 없습니다. 호출자는 이미이 시점에서 반환 값을 받고 앞으로 이동했습니다. – Evk

답변

5

yield returnreturn의 작동 방식과 거의 같습니다. 이터레이터의 경우이 두 가지 방법 중 하나를 사용할 수 있습니다.

public IEnumerable<int> SomeIterator() 
{ 
    for(int I = 0; I < 10; I++) yield return I; 
} 

public IEnumerable<int> SomeIterator() 
{ 
    return Enumerable.Range(0, 10); // return result of another iterator. 
} 

그러나 둘 다 가질 수는 없습니다. iterator는 yield으로 지연 반복을 처리하기 위해 컴파일러에 의해 클래스로 변환되거나 다른 것을 반환하는 다른 일반 메소드와 마찬가지로 작동하지 않기 때문에 작동하지 않습니다.

public IEnumerable<int> SomeIterator() // not valid 
{ 
    for(int I = 0; I < 10; I++) yield return I; 
    return Enumerable.Range(0, 10); 
} 

이야기는 returnasync/await에 대해 동일합니다. 반환 유형이 Task 인 메서드의 경우 Task을 반환하거나 async/await을 사용합니다.

Task<T>에 대한

당신이 사용하는 경우 당신이 T을 반환해야 기다리고 있지만, 방법은 상태 기계로 컴파일 때문에 Task<T>을 반환 할 수 없습니다, 다음 방법은 T을 반환해야합니다. (Task 방법은 무효입니다)

사용하지 않는 경우 async/await 방법은 다른 일반적인 방법과 똑같을 것입니다.

+0

이것은 Evk의 의견과 함께 많은 의미가 있습니다. 나는 여전히 다소 실망 스럽지만 'Thing1()을 기다리고있다. Thing2()를 기다린다. return '과'Thing1();을 기다린다. return Thing2();'두드러기에서 같은 코드로 간단히 컴파일하지 마십시오. 적어도 여전히 논리적 인 의미로 사용됩니다. – DJL

-2

당신은 또한 당신이 당신의 작업 복귀를 입력하는 지정해야

private async Task<SomeReturnType> SomeMethod() 
{ 
    SomeReturnType someResult = await DoSomethingAsync(); 
    return someResult; 
} 

할 수

private async Task<SomeReturnType> SomeMethod() 
{ 
    return await DoSomethingElseAsync(); 
} 

같은 것을해야한다. 그리고 이 비동기 작업을 기다려야합니다.

+0

그건 OP가 시도하고 작동하지 않았던 것입니다 –

+0

아마 그냥 작업을 반환하려고합니다. – Neuxz

+0

질문과 오류 메시지를 읽어주십시오. ** 비동기식 ** 메소드에서 아무 것도 반환 할 수 없습니다 **. 'async Task'는 메소드가 아니라 함수입니다. –

0

await을 사용하면 제어 흐름이 현재 방법을 벗어나서 발신자에게 돌아갈 수 있습니다. DoSomethingAsync이 장기 실행 작업이라고 가정합니다. SomeMethod으로 전화하십시오. DoSomethingAsync 작업이 시작되었지만 그 방법 내에서 작업이 완료 될 때까지 기다릴 수 없습니다. 그렇지 않으면 아무 것도 "비동기"가되지 않습니다. 따라서 제어 흐름은 Method으로 남으며 발신자에게 반환 값을 제공해야합니다. 반환 값은 전체 SomeMethod이 완료되면 완료되는 작업입니다. 결과 (Task 또는 Task<T> 반환 값)가 있든 없든 완료 할 수 있습니다.당신이 SomeMethod의 반환 형식 수 없습니다 await 후 반환 무슨 이유 - 그것은 단지 결과 유형 T 수 있습니다 간단 Task을 반환하는 경우 (SomeMethod 반환 작업하는 경우) 또는 return 단순한는 SomeMethod의 완료를 나타냅니다.

0

정상적인 방법에서 return은 "이 값이있는 경우 메서드에서 반환"을 의미합니다. async 메서드에서 return의 의미가 "반환되는 결과를이 값 (있는 경우)으로 설정"으로 변경됩니다.

두 가지를 결합 할 수는 없습니다. async Task 방법에서는 직접 을 사용할 수 없습니다. 그 이유 중 하나는 await이 처리 된 경우 실제로 메서드가 Task을 반환하고 다른 메서드를 반환 할 수 없다는 것입니다. 가 돌아 올 때

async Task 방법은 단지 return;을 허용에서는, void 방법처럼 동작하지만, 결코 return value;.

관련 문제