2

다음과 같은 구현이 있습니다.

Task<IEnumerable<Item1>> GetItems1() 
{
    return RunRequest(async () => ParseItemsFromResponse(await(httpClient.Get(..))));
}

Task<IEnumerable<Item2>> GetItems2() 
{
    return RunRequest(async () => ParseItemsFromResponse(await httpClient.Get(..)));
}


TResult RunRequest<TResult>(Func<TResult> req)
{
    try
    {
        return req();
    }
    catch (Exception ex)
    {
        // Parse exception here and throw custom exceptions
    }
}

문제는 익명의 무효 메서드입니다.async () => ParseItemsFromResponse(..).

그것은 무효가 아니기 때문에Task익명 메소드 내에서 예외가 발생하면 실제로는 catch되지 않습니다.trycatchRunRequest.

어떤 제안이 이것을 리팩토링하는 방법?


  • 다만돈 없음용도async void. 이벤트 핸들러 또는 이와 유사한 메소드를 수신하거나 처리 할 수없는 메소드에만 해당됩니다.Task결과. 님이 던진 예외는 없습니다.async void응용 프로그램의 처리되지 않은 예외 처리기를 제외하고 - Panagiotis Kanavos
  • 일반적으로 권장 사항비동기 함수와 함께 void를 사용합니다. - Bauss
  • 하다RunRequest~을 취하다Task대신에Func그리고httpClient.Get()직접? - Mats391
  • 컴파일러는 그것을 사용하지 않을 것이다.RunRequestParseItemsFromResponse가 뭔가를 반환하지 않으면 오버로드됩니다. 당신은 다른 것을 가지고 있습니까?Action? 이런 식으로하지 마십시오.var result=await httpClient.Get();ParseItems(result);깨끗하다. - Panagiotis Kanavos
  • @ Mats391은 좋은 생각인데, 왜 생각하지 않았습니까? 고마워요! - Don Box

1 답변


3

RunRequest~해야한다.Func<Task<TResult>>, 같은 :

async Task<TResult> RunRequestAsync<TResult>(Func<Task<TResult>> req)
{
  try
  {
    return await req().ConfigureAwait(false);
  }
  catch (Exception ex)
  {
    // Parse exception here and throw custom exceptions
  }
}

그럼 너의async람다는async Task<T>대신에 방법async void.

에 대한 자세한 정보가 있습니다.싱크 / 비동기 대의원내 블로그에.


  • 또한 전화 할 필요가 있습니까?ConfigureAwait(false)? 아니면 컨텍스트를 다시 전환하지 않는 최적화입니까? - Don Box
  • @DonBox : 단지 최적화에 불과합니다. - Stephen Cleary

연결된 질문


관련된 질문

최근 질문