12

비동기 메소드를 구현되지 않았거나 지원되지 않거나 유효하지 않은 것으로 표시하는 올바른 방법은 무엇입니까? 단순함을 위해서 나는NotImplementedException예를 들어, 질문은NotSupportedExceptionInvalidOperationException게다가.

동기화 방법으로 간단히 예외를 throw합니다.

public override void X() {
    throw new NotImplementedException();
}

비동기 세계에서이 코드와 동일한 것은 무엇입니까?

/* 1 */ public override Task XAsync() {
    throw new NotImplementedException();
}

또는

/* 2 */ public override Task XAsync() {
    return Task.FromException(new NotImplementedException());
}

이러한 접근법의 복잡성은 무엇입니까? 더 좋은 방법이 있습니까?


"Nah를 피하려면 여기서 비동기가 될 메소드가 필요 없습니다."/ "비동기가 아닙니다."메소드가 일부 인터페이스 또는 추상 클래스를 구현한다고합니다.


내가 고려하지 않고있는 몇 가지 방법 :

/* 3 */ public async override Task XAsync() { // here is an CS1998 warning 
    throw new NotImplementedException();
}

컴파일러쓸모없는 상태 기계를 생성 할뿐입니다., 이는 2와 의미 상 동일하다

/* 4 */ public async override Task XAsync() {
    await Task.Yield();
    throw new NotImplementedException();
}

이것은똑같다3로,하지만 Task.Yeild ();


  • 좋은 질문. 첫 번째 옵션은 메서드가 호출 될 때 예외를 throw하고 두 번째 옵션은 결과가 기다릴 때 예외를 throw합니다. 첫 번째 옵션에 대해서는 약간의 선호도가 있습니다. 왜냐하면 "일찍 실패"하기 때문에 전문가가 말하고자하는 것이 궁금합니다. - Heinzi
  • 아마도 도움이 될 것입니다.stackoverflow.com/a/13254787/316799 - Felipe Oriani
  • 그래, @ FelipeOriani, 그것을 보았다. 고마워. - hazzik
  • " 정확한 시나리오를 명확히하지 않으면 " 우리는 NHibernate의 비동기 버전을 만들기 위해 노력하고 있습니다 :)github.com/nhibernate/nhibernate-core/pull/588 - hazzik
  • @hazzik 예. 내 의견을 이해 못 했니? 말하고있다.async Task XAsync() { throw ...; }또 다른 옵션입니다. 와 더불어async예어. - user743382

3 답변


3

반환하는 메소드를 호출 할 때Task, 그것의 일부는 동 기적으로 실행됩니다 (구현 방법이async~ 있고await처음부터 그 모든 것이 기본적으로 동기식입니다.).

따라서 결과는 모든 옵션에 대해 동일합니다. 즉각 throw하거나 예외로 이미 완료된 Task를 반환합니다 (호출을 즉시 기다리는 경우에만 동일하게 동작 함). 또는 메서드를 표시합니다.async(당신이await호출하지만 완전성을 위해 추가하자).

나는 즉시 던져 버릴거야.Task를 반환하면 "작업을 시작했습니다."호출자는 작업을 기다릴 필요가 없습니다.그래서 발신자가 정말로 걱정하지 않는다면Task(리턴 값조차 가지고 있지 않다면) 메소드가 구현되지 않았다는 사실은 나타나지 않을 것입니다.


  • 이 문제에 관심이있는 동안 ... 거기서 BC를 만들지는 못합니다.   - micahhoover
  • 작업을 반환하는 메소드 만 가져 오는 경우에는 메소드를 정의하지 마십시오.async예어. - Martin Ullrich

4

나는 사지에 나가서 "그건 중요하지 않다"고 말할 것입니다.

Boneheaded 예외직접 던져 질 수있다.throw) 또는 반환 된 작업에 배치 (Task.FromException). 그들은 예외가 아니기 때문에 어쨌든 잡히지 않아야합니다. 그래서 어디서 던져 지든 상관 없습니다.


2

귀하의 의견에 다음과 같이 썼습니다 :

우리는 NHibernate의 비동기 버전을 만들기 위해 노력하고 있습니다 :)

숙련 된 프로그래머가 작성한 잘 알려진 라이브러리는 숙련되지 않은 프로그래머가 의도하지 않은 오용 (복사 / 붙여 넣기를 통한 오용 포함)을 방지하기 위해 잘 작성되어야합니다.

코드를 기대하는 사람이 충분히 있습니다.await Task.WhenAll(a(), b(), c())비동기 작업 중 하나가 실패하더라도 작업 할 수있는 첫 번째 옵션은 옵션이 아니어야합니다. 만약b()동 기적으로 예외를 던집니다.a()반환 된 작업이 무시되고c()부르지 않는다.

나는 Stephen Cleary의 대답에 동의한다.NotImplementedException그가 그것을두고 있듯이, 어쨌든 프로덕션 코드에서 결코 끝나지 않아야하므로 중요하지 않은 예외가 있습니다. 그러나 다음과 같이 작성합니다.

질문은NotSupportedExceptionInvalidOperationException게다가.

이것들은 꼭 골치 아픈 예외는 아닙니다. 이들할 수 있었다프로덕션 코드로 끝납니다.

두 번째 옵션은 문제를 피합니다.

두 번째 옵션에는 추가 문제가 있습니다. 예외가 발생하지 않습니다. 실제로 예외가 발생하지 않으므로 디버깅을 방해합니다. 문제가 발생하면 디버거에서 예외가 발생한 지점에서 깨는 옵션을 사용하는 것이 매우 유용합니다.던진그것이있는 곳보다잡힌.

나는 또한 고려할 것을 제안했다.

public async override Task XAsync() {
  throw new NotImplementedException();
}

이는 상태 시스템 작성과 관련된 오버 헤드로 인해 버려졌습니다. 나는 이것이 이것을 버리는 타당한 이유가 아니라고 생각한다. 이것은 성능이 관련이없는 코드이며 오류 케이스 만 처리하는 코드입니다. 나는 일반적으로, 나는 그것을 사용하기를 선호하기 때문에 그것을 제안했다.async/await개발 시간을 절약 할 수있는 시간은 충분히 가치가 있기 때문에 어리석은 실수를 잡는 것이 훨씬 쉽기 때문에 작업을 직접 조작하는 것보다 훨씬 쉽습니다.

왜이 옵션을 사용하고 싶지 않은지 이해하지만 개인적으로는 여전히 그렇습니다. 첫 번째 옵션의 단점을 피할 수 있습니다. 두 번째 옵션의 단점을 피할 수 있습니다. 약간의 성능 저하가있는 자체 단점은 내 경험상 다른 두 가지 문제보다 문제가 될 가능성이 적습니다.

다른 두 가지 중에서, 단점의 세부 사항이 당신이 정보에 입각 한 결정을 내리는 데 도움이되기를 바랍니다.

연결된 질문


관련된 질문

최근 질문