Task.FromResult 또는 Task.CompletedTask를 반환하지 마세요.

5135 단어 dotnetcsharp
따라서 기다릴 것이 없는 이 비동기 처리기 또는 인터페이스 메서드를 구현하고 다음과 같이 작성합니다.

async Task<bool> HandleAsync()
{
     DoSomethingSynchronous();
     return true;
}


그러나 이제 C# 컴파일러는 엄격한 경고를 내보냅니다. "CS1998: you're using async , so you should be await stuff! find something to await!"대신 async를 제거하고 Task.FromResult(true)를 반환합니다. Stackoverflow에서 top-ratedhigh-reputation members 답변을 권장하기 때문입니다. 작업이 완료되었습니다.

Task<bool> HandleAsync()
{
    DoSomethingSynchronous();
    return Task.FromResult(true);
}


아니면?
HandleAsync가 항상 호출되고 즉시 대기되는 한 모든 것이 정상입니다.

var success = await HandleAsync(); // This is fine.


그러나 어두운 위협이 그림자 속에 도사리고 있습니다. 가끔 try-catch가 예외를 포착하지 못하는 경우가 있습니다.

var task0 = a.HandleAsync();
var task1 = b.HandleAsync();

try
{
     await Task.WhenAll(new[] { task0, task1 });
}
catch (Exception ex)
{
    // this handler does nothing and the exception escapes! What gives??
}

HandleAsync는 실제로 동기식이므로 모든 예외는 기다릴 때가 아니라 호출되자마자 전파됩니다. 이것은 대부분의 C# 프로그래머에게 놀라운 일입니다. Task를 반환하는 동기식 메서드는 특히 SomethingAsync라고 하는 경우 예상한 것과 다릅니다. 놀랍게도 예상치 못한 동작으로 인해 버그가 발생합니다. 버그는 고객과 개발자 모두를 불행하게 만듭니다.

대신에 우리는 무엇을 해야 합니까?

한 가지 옵션은 경고 CS1998을 비활성화하는 것이지만 메서드가 처음부터 작업을 반환하지 않아야 하는 경우를 지적할 수 있습니다. 아마도 가장 좋은 방법은 함수를 async 및 awaitTask.FromResult로 표시하는 것입니다.

async Task<bool> HandleAsync()
{
    DoSomethingNotAsync();
    return await Task.FromResult(true);
}


또는 일반 Task , 대기 중Task.CompletedTask 인 경우.

async Task HandlerAsync()
{
    DoSomethingNotAsync();
    await Task.CompletedTask;
}


이렇게 느린가요? 그다지 많지 않음 - 완료된 작업을 기다리는 것은 거의 아무것도 하지 않으며 런타임은 이 일반적인 패턴을 인식하고 모든 오버헤드를 제거할 수 있습니다. "evil premature optimization ", 제 생각에는.

*실은 이렇게 말합니다

warning CS1998: This async method lacks ‘await’ operators and will run synchronously. Consider using the ‘await’ operator to await non-blocking API calls, or ‘await Task.Run(…)’ to do CPU-bound work on a background thread.

좋은 웹페이지 즐겨찾기