비동기 대기 반환 작업


131

누군가 이것이 동기 방식으로 무엇을 의미하는지 설명 할 수 있습니까? 내가 방법을 변경하려고하면 asyncVS가 그것에 대해 불평합니다.

이것은 작동합니다 :

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

작동하지 않습니다.

public async Task MethodName()
{
     return Task.FromResult<object>(null);
}

그래서 기본적으로 이것이 정확히 무엇을 의미하는지 알고 싶습니다. Task.FromResult<object>(null);



@LB 흠! 그러나 또한 내가 그냥 return;작동 한다면 ...!
David Dury

2
"작동하지 않습니다"는 작동하지 않는 것에 대한 아주 좋은 설명을 제공하지 않습니다. 수신되는 오류 메시지는 무엇입니까?
John Koerner

@ JohnKoerner 필자는 컴파일러가 void함수 에서 값을 반환하려고하는 것과 같은 오류를 줄 수 있다고 생각합니다 .
binki

답변:


236

async방법은 일반적인 방법과 다릅니다. async메소드 에서 반환하는 것은 무엇이든 에 싸여 Task있습니다.

값을 반환하지 않으면 (void) 래핑되고 Task, 반환 int하면 래핑 Task<int>됩니다.

비동기 메서드를 반환 해야하는 경우 메서드 int의 반환 유형을로 표시 Task<int>하고를 int아닌 일반을 반환 합니다 Task<int>. 컴파일러는 변환됩니다 int에를 Task<int>당신을 위해.

private async Task<int> MethodName()
{
    await SomethingAsync();
    return 42;//Note we return int not Task<int> and that compiles
}

마찬가지로, Task<object>메소드 를 리턴 할 때 리턴 유형은Task<Task<object>>

public async Task<Task<object>> MethodName()
{
     return Task.FromResult<object>(null);//This will compile
}

메소드가를 Task반환하므로 값을 반환해서는 안됩니다. 그렇지 않으면 컴파일되지 않습니다.

public async Task MethodName()
{
     return;//This should work but return is redundant and also method is useless.
}

await명령문이없는 비동기 메소드 는 그렇지 않습니다 async.


1
나 에게이 반환 유형이 작동하지 않습니다 (뭔가 잘못하고있는 것 같습니다). 정적 비동기 작업 <string> DoStuff () {... = await SomeMethodAsync (); "문자열 값"을 반환합니다. } .. var x = DoStuff (); 그러나이 x- 유형은 "string"이 아니라 "Task <string>"유형입니다. 왜 그렇습니까?
Prokurors

3
@Prokurors DoStuff()또한 기다려야 합니다. 예를 들면 :var x = await DoStuff();
스리 람 Sakthivel

5
되어야합니다return await Task.FromResult<object>(null);
sandeep talabathula

@sandeeptalabathula는 null을 반환하는 것과 동일
Sriram Sakthivel

2
@ProfK Task.WhenAny가 예입니다.
Servy

55

async를 사용할 때 await 키워드를 사용해야하며 함수 반환 유형이 일반적이어야합니다. 반환 값이있는 예는 다음과 같습니다.

public async Task<object> MethodName()
{
    return await Task.FromResult<object>(null);
}

다음은 반환 값이없는 예입니다.

public async Task MethodName()
{
    await Task.CompletedTask;
}

이것들을 읽으십시오 :

TPL : http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx 및 작업 : http://msdn.microsoft.com/en-us/library/system.threading .tasks (v = vs.110) .aspx

비동기 : http://msdn.microsoft.com/en-us/library/hh156513.aspx 기다립니다 : http://msdn.microsoft.com/en-us/library/hh156528.aspx


9
null더미 작업을 기다리는 대신 직접 돌아올 수 있습니다 .
Lee

5
@Lee, 그러나 그렇게하면 컴파일러는 async메소드의 await어딘가에서 키워드 를 사용하라는 제안과 함께 메소드가 비동기 적으로 실행 된다고 불평합니다 (경고) . 컴파일러 경고 소음을 줄이기 위해 키워드를 사용 return Task.FromResult((object)null);하고 제거하는 것이 좋습니다 async.
binki

예, return작업에서 사용하려고 했지만 작업이 계속 실행됩니다 return.Task
Turner Bass

30

비동기 키워드를 추가하는 것은 상태 머신의 작성을 단순화하기 위해 구문 설탕입니다. 본질적으로 컴파일러는 코드를 가져옵니다.

public async Task MethodName()
{
     return null;
}

그리고 그것을 바꿉니다.

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

코드에 await키워드 가있는 경우 컴파일러는 메소드를 가져 와서이를 실행하는 데 필요한 상태 머신을 나타내는 클래스로 변환해야합니다. 각 await키워드에서 변수의 상태와 스택은 클래스의 필드에 보존되며 클래스는 대기중인 작업에 완료 후크로 추가 된 다음 반환됩니다.

해당 작업이 완료되면 작업이 다시 실행됩니다. 따라서 변수의 상태를 복원하고 코드의 다음 슬래브로 이동하기 위해 메소드 상단에 일부 추가 코드가 추가됩니다.

async & await는 무엇을 생성합니까?를 참조하십시오 . 까다로운 예를 들어.

이 프로세스는 컴파일러가 yield 문으로 반복자 메서드를 처리하는 방식과 많은 공통점이 있습니다.


2

이것은 String 유형의 작업을 반환하는 작업입니다 (C # 익명 함수 또는 다른 말로 위임이 'Func'사용됨).

    public static async Task<string> MyTask()
    {
        //C# anonymous AsyncTask
        return await Task.FromResult<string>(((Func<string>)(() =>
        {
            // your code here
            return  "string result here";

        }))());
    }

1
답변으로 코드를 게시 할 때 시연 내용에 대한 설명을 포함하십시오. 이 경우 이미 여러 개의 답변이있는 이전 질문에 대한 답변을 추가하고 있습니다. 새 답변이 시연하는 내용을 설명하는 문장을 하나 또는 두 개 추가하십시오. 다른 답변에는 아직 표시되지 않았습니다. 나는 당신이 당신의 코드로 보여주고있는 것을 단어로 넣어서 다른 사람들을 도와달라고 요구하면서 당신의 대답에 잘못된 것을 말하는 것이 아닙니다.
ToolmakerSteve

0

비동기 메소드에서 올바른 응답을 다시 얻으려면 해당 태스크 메소드를 호출하는 동안 대기해야합니다. 작업 유형이 아닌 반환 값 유형으로 다시 변환되기를 기다립니다.

예를 들어 var content = await StringAsyncTask (

여기서 public async Task < String > StringAsyncTask ())

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.