거기 있니?어떤시나리오 작성 방법은 다음과 같습니다.
public async Task<SomeResult> DoSomethingAsync()
{
// Some synchronous code might or might not be here... //
return await DoAnotherThingAsync();
}
대신이 :
public Task<SomeResult> DoSomethingAsync()
{
// Some synchronous code might or might not be here... //
return DoAnotherThingAsync();
}
말이 되겠습니까?
왜 사용 하는가?return await직접 돌아올 수있을 때 구성Task<T>안쪽에서DoAnotherThingAsync()기도?
나는 코드를 본다.return await여러 곳에서 나는 뭔가를 놓쳐 야한다고 생각합니다. 그러나 내가 이해하는 한,이 경우에는 async / 키워드를 기다리지 않고 Task를 직접 반환하는 것이 기능적으로 동일합니다. 추가 오버 헤드를 추가하는 이유await층?
다음 경우에 한 가지 비열한 경우가 있습니다.return정상적인 방법으로return await...에서async메소드가 다르게 동작합니다.using(또는 더 일반적으로return await안에try블록).
다음 두 가지 버전의 메소드를 고려하십시오.
Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return foo.DoAnotherThingAsync();
}
}
async Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return await foo.DoAnotherThingAsync();
}
}
첫 번째 방법은Dispose()그만큼Foo되 자마자DoAnotherThingAsync()메서드가 반환됩니다. 실제로 완료되기 훨씬 전에 발생합니다. 즉, 첫 번째 버전은 버그가있을 수 있습니다 (왜냐하면Foo너무 빨리 처리됩니다.), 두 번째 버전은 정상적으로 작동합니다.
foo.DoAnotherThingAsync().ContinueWith(_ => foo.Dispose()); - ghordDispose()보고void. 너는 비슷한 것을 필요로 할거야.return foo.DoAnotherThingAsync().ContinueWith(t -> { foo.Dispose(); return t.Result; });. 하지만 두 번째 옵션을 사용할 수있는 이유는 무엇입니까? - svick{ var task = DoAnotherThingAsync(); task.ContinueWith(_ => foo.Dispose()); return task; }. 유스 케이스는 매우 간단합니다. .NET 4.0 (대부분)과 같은 경우, 비동기 코드를이 방식으로 작성할 수 있습니다.이 방식으로 4.5 앱에서 제대로 호출됩니다. - ghordFoo반환 된 후에 만Task완료하지 않습니다. 동시성을 불필요하게 도입하기 때문에 마음에 들지 않습니다. - svick
필요없는 경우async(즉,Task직접) 사용하지 마십시오.async.
몇 가지 상황이 있습니다.return await당신이 가진 것처럼 유용하다.두비동기 작업 :
var intermediate = await FirstAsync();
return await SecondAwait(intermediate);
자세한 내용async성능은 Stephen Toub 's를 참조하십시오.MSDN 기사과비디오주제에.
최신 정보:나는블로그 게시물그것은 훨씬 더 자세하게 설명됩니다.
await두 번째 경우에 유용합니까? 왜 안돼?return SecondAwait(intermediate);? - Matt Smithreturn SecondAwait(intermediate);이 경우에도 목표를 달성 할 수 있을까요? 나는 생각한다.return await여기에도 중복됩니다 ... - TX_await첫 번째 줄에서는 두 번째 줄에서도 사용해야합니다. - svickasync버전에서 사용할적게동기화 버전보다 리소스 (스레드)가 많습니다. - svickSecondAwaitCS4016 : 이것은 비동기식 메소드이므로, 리턴 표현식은 & # 39; 문자열 & # 39; 유형이어야합니다. & lt; 작업 & lt; 문자열 & gt; & quot; & quot; - svick
네가하고 싶은 유일한 이유는 다른 것이 있으면await이전 코드에서, 또는 결과를 조작하기 전에 결과를 조작하는 경우. 그것이 일어날 수있는 또 다른 방법은try/catch예외가 처리되는 방식이 변경됩니다. 네가 맞다면 그 중 하나를 수행하지 않는다면 메소드를 만드는 오버 헤드를 추가 할 이유가 없다.async.
return await자식 호출의 태스크를 반환하는 대신에) 필요하다.이전 코드에서 기다리고있는 다른 것이 있더라도. 설명해 주시겠습니까? - TX_async그러면 첫 번째 과제는 어떻게 기다리고 있을까요? 메소드를 다음과 같이 표시해야합니다.async당신이 사용하고 싶다면어떤기다리고있어. 메소드가 다음과 같이 표시되면async너는await이전 코드에서는await두 번째 비동기 작업은 적절한 유형이어야합니다. 방금 제거한 경우await반환 값이 적절한 유형이 아니므로 컴파일되지 않습니다. 이 방법은async결과는 항상 태스크에 랩핑됩니다. - Servyasync메서드를 사용하여 작업을 반환하지 않으면 작업의 결과를 반환 한 다음 래핑됩니다. - ServyTask<Type>명시 적으로, whileasync돌아 오는 것을 명령하다Type(컴파일러 자체가Task<Type>). - noseratioasync연속체를 명시 적으로 연결하기위한 문법적 설탕 일뿐입니다. 너는 몰라.필요한 것
async무엇이든 할 수 있지만, 비범 한 비동기 작업을 수행 할 때는극적으로함께 일하기가 쉽다. 예를 들어, 제공 한 코드가 실제로 원하는대로 오류를 전달하지 못하고 더 복잡한 상황에서 올바르게 수행하면 훨씬 더 어려워집니다. 너는 절대로필요한 것
async, 내가 기술 한 상황은 그것을 사용하는 가치를 부가하는 곳이다. - Servy
결과를 기다리는 또 다른 경우는 다음과 같습니다.
async Task<IFoo> GetIFooAsync()
{
return await GetFooAsync();
}
async Task<Foo> GetFooAsync()
{
var foo = await CreateFooAsync();
await foo.InitializeAsync();
return foo;
}
이 경우,GetIFooAsync()~의 결과를 기다려야한다.GetFooAsync유형이T두 가지 방법이 다르다.Task<Foo>에 직접 할당 할 수 없다.Task<IFoo>. 하지만 결과를 기다리고 있다면Foo어느~이다.에 직접 할당 할 수있는IFoo. 그런 다음 비동기 메서드는 내부에서 결과를 리 패키징합니다.Task<IFoo>그리고 멀리 가라.
달리 간단한 "썽크"메서드를 비동기로 만들면 메모리에 비동기 상태 시스템이 만들어지며 비동기식 모드 시스템에서는 그렇지 않습니다. 더 비효율적 인 버전을 사용하는 것은 종종 비효율적 인 버전을 사용하는 것을 가리킬 수 있지만 (사실입니다), 이는 정지 상태 인 경우 해당 메소드가 "리턴 / 연속 스택"과 관련되어 있다는 증거가 없음을 의미합니다. 때로는 걸림쇠를 이해하는 것을 더 어렵게 만듭니다.
그래서 예, 퍼프가 중요하지 않을 때 (그리고 대개는 그렇지 않습니다) 나는이 모든 썽크 메서드에 비동기를 던져서 나중에 비상 정지 상태를 진단 할 수있게 도와줍니다. 썽크 (thunk) 방법은 시간이 지남에 따라 진화 해 나간다. 던진 것이 아니라 잘못 된 작업을 반드시 되돌려 놓을 것이다.
이것은 또한 나 혼란스럽고 이전 답변이 실제 질문을 간과했다고 생각합니다.
내부 DoAnotherThingAsync () 호출에서 Task를 직접 반환 할 수있는 경우 return을 사용하는 이유는 무엇입니까?
가끔 당신 이요.사실은~을 원한다Task<SomeType>, 그러나 대부분의 경우 실제로 인스턴스를 원한다.SomeType, 즉 작업의 결과입니다.
귀하의 코드에서 :
async Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return await foo.DoAnotherThingAsync();
}
}
구문에 익숙하지 않은 사람 (예를 들어)은이 메서드가Task<SomeResult>, 표시되어 있기 때문에async, 실제 리턴 유형은 다음과 같습니다.SomeResult.
방금 사용하면return foo.DoAnotherThingAsync(), 컴파일하지 않는 Task를 반환 할 것입니다. 올바른 방법은 작업 결과를 반환하는 것입니다.return await.
var task = DoSomethingAsync();너에게 과제를 주겠다.T - Shoeasync/await의회. 나의 이해에,Task task = DoSomethingAsync(), 동안Something something = await DoSomethingAsync()둘 다 작동합니다. 첫 번째는 적절한 작업을 제공하고 두 번째는await키워드를 사용하면결과완료 후 작업에서. 예를 들어 나는Task task = DoSomethingAsync(); Something something = await task;. - heltonbiker