C #에서 재정의를 비 동기화 할 수있는 이유는 무엇입니까?


16

C #에서는 메서드를 재정의하는 경우 원래 메서드가 아닌 경우 재정의를 비동기로 만들 수 있습니다. 이것은 형편없는 것 같습니다.

이 문제를 해결 한 예는 다음과 같습니다.로드 테스트 문제를 해결하기 위해 들어 왔습니다. 약 500 명의 동시 사용자에서 로그인 프로세스는 리디렉션 루프에서 중단됩니다. IIS가 "비동기 작업이 아직 보류중인 동안 비동기 모듈 또는 처리기가 완료되었습니다"라는 메시지와 함께 예외를 기록하고있었습니다. 일부 검색으로 인해 누군가가 학대하고 있다고 생각 async void했지만 소스를 통한 빠른 검색으로 아무것도 찾을 수 없었습니다.

슬프게도, 나는 'async \ s [^ T]'와 같은 것을 찾고 싶을 때 'async \ svoid'(정규 검색)를 검색했습니다 (작업이 정규화되지 않았다고 가정하면 요점을 얻습니다).

나중에 찾은 것은 async override void onActionExecuting(...기본 컨트롤러에있었습니다. 분명히 그것은 문제가되었고, 그것은 문제였습니다. 이를 수정하면 (순간 동기화) 문제가 해결되었습니다.

질문으로 돌아 가기 : 왜 호출 코드가이를 기다릴 수 없을 때 대체를 비동기로 표시 할 수 있습니까?



호출자가 재정의 된 메서드를 기다리는 것을 정확히 방해하는 것은 무엇입니까? 장애물이 보이지 않습니다.
Martin Maat

@MartinMaat 반환하는 메서드 만 기다릴 수 있습니다 Task.
Derek Elkins가 SE

아마도 그것은 내가 알지 못했던 좋은 지적 일 것입니다. 확인해야하지만 대기하지 않고 비동기가 아닌 메소드를 호출하는 것에 대한 VS 경고를 상기하지 않습니다.
Peter T. LaComb Jr.

답변:


16

비동기 키워드는 허용 방법 을 사용하는 await자사의 정의에 구문을. 비동기 메소드인지 여부에 관계없이 유형 await을 반환하는 모든 메소드에서 사용할 수 있습니다 Task.

void비동기 메소드에 대한 합법적 인 ( 권장 되지는 않지만) 반환 유형이므로 왜 허용되지 않습니까? 외부에서, async당신이 그것 없이는 할 수 없었던 것을 가능하게하지 않습니다. 문제가있는 방법은 비동기없이 정확하게 동일하게 작동하도록 작성되었을 수 있습니다. 그 정의는 더 장황했을 것입니다.

발신자하기 위해, async T이 반환하는 정상적인 방법 T(이에 한정되는 void, Task또는은 Task<A>). 비동기 메소드라는 것은 인터페이스의 일부가 아닙니다. 다음 코드는 불법입니다.

interface IFoo {
    async void Bar();
}

VS2012에서 (또는 추상 클래스의 유사한 코드) 다음과 같은 오류 메시지가 생성됩니다.

'비동기'수정자는 명령문 본문이있는 메소드에서만 사용할 수 있습니다.

내가하면 일반적으로 비동기로 인터페이스 또는 부모 클래스의 메소드를 의도, 내가 사용할 수 없습니다 async그 의사 소통 할 수 있습니다. await구문 을 사용하여 구현 하려면 비동기 재정의 메소드를 가질 수 있어야합니다 (부모 클래스의 경우).


1
당신은 전혀 언급하지 않지만 override, 그것이 문제에 관한 것입니다.
Nathan Tuggy 2016 년

4
@NathanTuggy 대답의 요점은 async메소드의 인터페이스를 변경하지 않으며 정의에서 구문 적으로 허용되는 것만이므로 재정의 여부에 관계없이 완전히 관련이 없습니다.
Derek Elkins

1
모든 사람들이 이미 모든 것을 알고 있다고 가정하지 말고 설명 하십시오 .
Nathan Tuggy 2016 년

2
@NathanTuggy 나는 그것을 설명했다고 생각합니다. 혼란 스러울 수있는 특정 질문을하거나 다른 혼란스러워하는 사람이 물을 것이라고 상상할 수 있습니까? 내가 추가 할 수있는 유일한 것은 async수정자가 구현에만 적용될 수 있음을 지적하는 것입니다 . 메소드가 비동기인지 여부가 인터페이스의 일부가 아닌지 여부를 강조하는 등 인터페이스에서 메소드를 비동기로 선언 할 수 없습니다.
Derek Elkins가 SE

5
대답에 설명 넣으십시오 . 그것은 장기적으로 주석이 아닙니다.
Nathan Tuggy

10

async 키워드의 유일한 목적은 해당 함수의 본문 내에서 키워드를 기다리는 것입니다. 대기 기능을 추가해도 기존 코드가 손상되지 않도록해야합니다. Microsoft는 옵트 인 옵션 대기를 사용하기로 결정했습니다. 비동기로 표시되지 않은 함수의 경우 문제없이 await라는 변수를 정의 할 수 있습니다.

따라서 비동기는 함수 서명의 일부가 아니며 생성 된 IL 코드에서 의미가 없습니다. 컴파일러가 함수를 올바르게 컴파일하는 방법을 알아야합니다. 또한 Task, Task <T> 또는 void 만 반환되도록 컴파일러에 지시합니다.

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