메서드 이름에 "Async"접미사를 사용하는 것은 'async'수정자를 사용하는지 여부에 따라 달라 집니까?


107

"Async"로 메서드 이름을 접미사하는 규칙은 무엇입니까?

"비동기"접미사를 추가해야합니까? async한정자 로 선언 된 메서드 에만 합니까?

public async Task<bool> ConnectAsync()

아니면 메서드가 반환 Task<T>하거나Task 합니까?

public Task<bool> ConnectAsync()

4
이름 지정 부분에 대해 TAP 문서 는 다음과 같이 말합니다. TAP의 비동기 메서드에는 작업 이름 뒤에 Async 접미사가 포함됩니다. 예를 들어, get 작업의 경우 GetAsync입니다. Async 접미사가있는 해당 메서드 이름이 이미 포함 된 클래스에 TAP 메서드를 추가하는 경우 대신 TaskAsync 접미사를 사용합니다. 예를 들어 클래스에 이미 GetAsync 메서드가있는 경우 이름 GetTaskAsync를 사용합니다.
James Manning

4
좋아, 내가 "비동기 방법에 대한 명명 규칙"의 질문 제목 혼란 한 생각
제임스 매닝을

1
이것은 잘못 구성된 질문입니다. 사람들은 다투고 모호한 대답을합니다.
누가 복음 Puplett

4
많은 사람들이 그것을 오해하고 실제 질문에 대해 논쟁하고 있기 때문에 그것이 두 부분으로 된 질문인지 궁금해합니다. 혼란스러운 증거는 사람들이 혼란스러워한다는 것입니다.
누가 복음 Puplett

2
@DavidRR 오늘날까지 나는이 질문이 분명히 야기한 혼란의 양을 여전히 이해하지 못합니다. 당신의 편집이 당신을 도왔고 다른 사람들을 도울 수있을 정도로 혼란 속에서 어떤 순서를 가져 오면, 나는 당신의 편집이 원래 공식에서 할 수 없었던 것을 성취 한 것을 환영합니다. 이제 질문이 너무 오래되어 여기에서 물었을 때의 사고 방식을 거의 기억할 수 없으므로 원래 의도가 덜 중요합니다. 누가의 대답은 모두가 혼란스러워하지 않았다는 것을 반영합니다. 나는 그것이 대단히 도움이된다는 것을 알았다.
kasperhj

답변:


128

Microsoft 문서에서도 진실이 모호하다고 생각합니다.

Visual Studio 2012 및 .NET Framework 4.5에서 async키워드 ( AsyncVisual Basic의 경우) 로 지정된 모든 메서드 는 비동기 메서드로 간주되며 C # 및 Visual Basic 컴파일러는 TAP를 사용하여 메서드를 비동기 적으로 구현하는 데 필요한 변환을 수행합니다. 비동기 메서드는 Task또는 Task<TResult>개체를 반환해야 합니다.

http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx

그것은 이미 옳지 않습니다. 모든 메서드 async는 비동기식이므로 호출 스택의 맨 위에있는 메서드 (예 : Button_Click 또는)에 적합하지 않은 Task또는 Task<T>-를 반환해야합니다 async void.

물론 대회의 요점이 무엇인지 고려해야합니까?

Async접미사 규칙은 메서드가 대기 가능하다는 것을 API 사용자에게 전달하는 것이라고 말할 수 있습니다. 메서드가 기다릴 수 있으려면 Taskvoid 또는 Task<T>값 반환 메서드에 대해 반환해야합니다. 즉, 후자에만 접미사 가 붙을 수 있습니다 Async.

또는 Async접미사 규칙은 메서드가 즉시 반환 될 수 있음을 알리고 현재 스레드가 다른 작업을 수행하도록 포기하고 잠재적으로 경쟁을 유발할 수 있음을 알리는 것이라고 말할 수 있습니다.

이 Microsoft 문서 인용문은 다음과 같습니다.

규칙에 따라 Async 또는 async 한정자가있는 메서드 이름에 "Async"를 추가합니다.

http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention

반환하는 자신의 비동기 메서드 TaskAsync접미사 가 필요 하다는 사실도 언급하지 않습니다 . 우리 모두 동의한다고 생각합니다.


따라서이 질문에 대한 답은 둘 다일 수 있습니다. 두 경우 모두 추가 할 필요 Async와 방법에 async키워드를 돌려 TaskTask<T>.


나는 상황을 명확히하기 위해 Stephen Toub에게 요청할 것입니다.

최신 정보

그래서 했어요. 그리고 우리의 선한 사람이 쓴 글은 다음과 같습니다.

공용 메서드가 작업 반환이고 본질적으로 비동기 인 경우 (항상 완료 될 때까지 동 기적으로 실행되지만 어떤 이유로 여전히 작업을 반환하는 것으로 알려진 메서드와는 반대로) "Async"접미사가 있어야합니다. 그것이 지침입니다. 여기서 이름 지정의 주요 목표는 호출되는 메서드가 모든 작업을 동 기적으로 완료하지 못할 가능성이 있다는 것을 기능 소비자에게 매우 분명하게 만드는 것입니다. 물론 기능이 동기 및 비동기 메서드를 사용하여 노출되는 경우에도 도움이되므로 구분하기 위해 이름 차이가 필요합니다. 메서드가 비동기 구현을 달성하는 방법은 명명에 중요하지 않습니다. async / await가 컴파일러의 도움을받는 데 사용되는지 또는 System.Threading.Tasks의 형식과 메서드가 직접 사용되는지 (예 : 지. TaskCompletionSource)는 메서드의 소비자에 관한 한 메서드의 서명에 영향을 미치지 않으므로 실제로 중요하지 않습니다.

물론 가이드 라인에는 항상 예외가 있습니다. 이름 지정의 경우 가장 주목할만한 것은 전체 유형의 이유가 비동기 중심의 기능을 제공하는 것입니다.이 경우 모든 메서드에 Async를 사용하는 것은 과도 할 수 있습니다 (예 : 다른 작업을 생성하는 Task 자체의 메서드). .

무효 반환 비동기 메서드의 경우 호출자가 비동기 작업이 언제 완료되었는지 알 수있는 좋은 방법이 없기 때문에 공용 노출 영역에있는 것은 바람직하지 않습니다. 그러나 무효 반환 비동기 메서드를 공개적으로 노출해야하는 경우 비동기 작업이 시작되고 있음을 전달하는 이름을 원할 가능성이 높으며 의미가 있으면 여기에 "Async"접미사를 사용할 수 있습니다. 이 사건이 얼마나 드문 지 감안할 때 나는 그것이 실제로 사례 별 결정이라고 주장합니다.

도움이 되길 바랍니다, 스티브

Stephen의 서두 문장의 간결한 지침은 충분히 명확합니다. async void비동기 void를 구현하는 올바른 방법은 일반 Task인스턴스 를 반환 하고 컴파일러가 마법을 사용하도록하는 것이기 때문에 이러한 디자인으로 공용 API를 생성하는 것은 드문 일이기 때문에 제외됩니다 . 그러나 원하는 경우 public async void추가하는 Async것이 좋습니다. async void이벤트 핸들러와 같은 다른 최상위 스택 메서드는 일반적으로 공개되지 않으며 중요하지 않습니다.

나에게는에 접미사 Async에 대해 궁금한 점이 있으면 호출자가 기다릴 수 있도록를 async void로 바꾸고 .async TaskAsync


20
메쏘드 호출에 대한 컴파일 시간 검사가 없다는 것은 아쉽습니다. 오 잠깐만 요. 메서드 이름을 Get 또는 GetAsync로 지정 하고 호출 측에서 await 를 사용하지 않으면 컴파일이 빌드되지 않습니다. 이 협약은 바보 정말 같은 것들을 피처럼, 많은 마이크로 소프트 스타일 지침에 가고 그래서 PersonStringPriceDecimal왜 사용 GetAsync- 비동기 API의 필요에 요청 항상 반환 모든 작업 후 완료 어쨌든으로 이것에 대해 걱정하지의 API 소비자. 어리 석고 정말 짜증나. 그러나 아무도 그 이유를 실제로 알지 못하는 또 다른 관습입니다.
Piotr Kula

2
@ppumkin : Stephen이 지적했듯이 메서드는 async / await를 사용하지 않고 본질적으로 쉽게 비동기적일 수 있으므로 호출자는 기능이 비동기 적으로 실행되는지 여부에 관계없이 이름 이외의 다른 표시가 없습니다.
Hannobo

6
@ppumkin : 기본적으로 비동기 메서드를 기다리지 않으면 컴파일 시간 경고가 발생합니다. 빌드 오류가 아닙니다.
Dustin Cleveland

7
이 컨벤션은 어리석은 것 같습니다. 메서드가 비동기라는 세 가지 자동 표시가 있습니다. 1. 반환 유형은 작업입니다. 2. 코드 완성은 기다릴 수있는 힌트를 제공합니다. 3. IDE는 녹색 밑줄과 컴파일러 경고를 표시하여 경고합니다. 그래서 저는 @ppumkin에 전적으로 동의합니다. Async 접미사는 public Lazy <Customer> CustomerLazy와 같은 속성을 작성한 것처럼 어리 석습니다. 누가 이럴거야! ??
Marco

2
@Marco 나는 GitHub에서이 아이디어를 제기했고, 그것이 최고의 장소라고 생각했지만, 내가 얻을 것이라고 생각한 참여가 없었다 : github.com/dotnet/core/issues/1464
Luke Puplett

68

필자는 대부분의 코드가 비동기 적으로 실행되는 다른 시스템을 호출하는 많은 API 서비스 및 기타 애플리케이션을 빌드합니다.

내가 따르는 내 자신의 경험 법칙은 다음과 같습니다.

동일한 것을 반환하는 비동기 및 비동기 메서드가 모두있는 경우 비동기 메서드를 Async로 접미사합니다. 그렇지 않으면 아닙니다.

예 :

한 가지 방법 :

public async Task<User> GetUser() { [...] }

두 개의 서명이있는 동일한 방법 :

public User GetUser() { [...] }

public async Task<User> GetUserAsync() { [...] }

반환되는 데이터는 동일하지만 데이터 자체가 아니라 데이터를 반환하는 방법 만 다릅니다 .

또한 비동기 메서드를 도입하고 이전 버전과의 호환성을 유지해야하기 때문에이 명명 규칙이 존재한다고 생각합니다.

나는 새로운 코드가 Async 접미사를 사용해서는 안된다고 주장합니다. 이 스레드에서 이전에 언급했듯이 String 또는 Int의 반환 유형만큼 분명합니다.


8
저는 특히 일반적으로 '모든 방법을 비 동기화'해야한다는 점에 동의합니다.이 경우 접미사가 중복됩니다. 코드의 90 %에 추가하는 것이 중요합니다.)
Bartosz

3
이것이 최상의 솔루션입니다. 눈치 채지 못한 채 API에서 동일한 방식으로 수행했습니다.
Marco

2
이것은 더 나은 부기의 사랑의 "비동기"비동기 응용 프로그램의 모든 방법보다 방법입니다
MARIUSZ Jamro

이 기술의 문제점은 나중에 비동기 버전을 만들 경우 선호하는 "GetUser ()"이름을 사용할 수 없다는 것입니다.
데이비드

3
이것이 실용적인 방법입니다. async 한정자가있는 모든 메서드에 Async를 추가하는 것은 Hungarian Notation 2019 일뿐입니다. @David 나중에 비동기 버전을 추가하는 경우 메서드 이름을 바꾸고 명명 규칙을 따르거나 그렇게하지 마십시오.
Skrymsli

25

"Async"로 메소드 이름을 접미사하는 규칙은 무엇입니까?

작업 기반 비동기 패턴 (TAP) 방법은 항상 반환하도록 지시 Task<T>(또는 Task)와 함께라는 이름 비동기 접미사; 이것은의 사용과는 별개입니다 async. Task<bool> Connect()및 둘 다 잘 컴파일되고 실행되지만 TAP 명명 규칙을 따르지 않을 것입니다.asyncTask<bool> Connect()

메서드에 async수정자가 포함되어야합니까 , 아니면 Task를 반환 할만큼 충분합니까?

(에 관계없이 반환 형식 또는 이름의) 방법의 몸이 포함되어있는 경우 await, 당신은 해야한다 사용 async; 컴파일러는 " 'await'연산자는 비동기 메서드 내에서만 사용할 수 있습니다. ..."라고 알려줍니다. 반환 Task<T>또는 Task사용을 피할 "충분하지"않습니다async . 자세한 내용은 비동기 (C # 참조) 를 참조하세요.

즉, 다음 서명 중 올바른 것은 무엇입니까?

모두 와 제대로 TAP 규칙을 따릅니다. 항상 키워드를 사용할 수 있지만 본문에서 .NET Framework를 사용하지 않으면 "이 비동기 메서드에는 'await'연산자가 없으며 동 기적으로 실행됩니다. ..."라는 컴파일러 경고가 표시됩니다 .asyncTask<bool> ConnectAsync()Task<bool> ConnectAsync()asyncawait


1
그는 async키워드 사용 여부가 아니라 메서드 이름에 "Async"를 추가할지 여부를 언급하고 있습니다 .
Servy 2011-04-11

1
@Servy 키워드 사용 여부 async는 질문의 두 번째 부분입니다.
Corak 2013-04-11

2
@Servy 두 부분으로 구성된 질문입니다. 말했듯이 첫 번째 부분은 메서드 이름에 "Async"를 추가할지 여부입니다. 두 번째 부분은 async수정자를 사용할지 여부 입니다. OPs 예제, public async Task<bool> ConnectAsync()( async수정 자 포함) 대 public Task<bool> ConnectAsync()( 수정 자 없음) 도 참조하십시오 async. 메서드 이름 자체에는 두 경우 모두 접미사 "Async"가 있습니다.
Corak 2013-04-11

2
두 부분으로 된 질문 이 아닙니다 . 문제는 "Async"를 반환하는 메서드의 메서드 이름 Task이나 async Task.
kasperhj

3
@lejon : 질문을 개선해야합니다. "vs." 코드 스 니펫은 유일한 차이점이기 때문에 비동기에 관한 질문 (전체적으로)을 분명히합니다.
Ðаn 2013

11

아니면 그냥 Task를 반환하는 것으로 충분합니까?

그. 여기서 async키워드는 실제 문제가 아닙니다. async키워드 를 사용하지 않고 비동기를 구현하는 경우 메서드는 일반적으로 여전히 "비동기"입니다.


7

이후 TaskTask<T>두 awaitable 유형은, 그들이 대표하는 몇 가지 비동기 작업을. 아니면 적어도 그들은 대표해야합니다.

Async일부 경우 (반드시 전부는 아님) 값을 반환하지 않고 진행중인 작업에 대한 래퍼를 반환하는 접미사 를 메서드에 추가해야 합니다. 이 래퍼는 일반적으로 Task이지만 Windows RT에서는 IAsyncInfo. 직감을 따르고 코드 사용자가 Async함수를 보면 해당 메서드의 호출이 해당 메서드의 결과와 분리되어 그에 따라 행동해야한다는 것을 알 수 있습니다.

이 같은 방법이 있습니다하는 것으로 Task.Delay하고 Task.WhenAll있는 반환 Task이 없어 아직 및Async 접미사.

또한 async void 을 나타내고 비동기 메서드를 잊어 버리는 메서드가 있으며 메서드가 이러한 방식으로 빌드된다는 사실을 더 잘 알고 있어야합니다.


6

메서드가 다음과 같이 선언되었는지 여부에 관계없이 Task를 반환하면 Async-suffix를 사용해야한다고 주장합니다. async 수정 자로 .

그 이유는 이름이 인터페이스에 선언되어 있기 때문입니다. 인터페이스는 반환 유형을 선언합니다 Task. 그런 다음 해당 인터페이스의 두 가지 구현이 있습니다. 한 구현은 async수정자를 사용하여 구현하고 다른 구현은 구현 하지 않습니다.

public interface IFoo
{
    Task FooAsync();
}

public class FooA : IFoo
{
    public Task FooAsync() { /* ... */ }
}

public class FooB : IFoo
{
    public async Task FooAsync() { /* ... */ }
}

이건 정말 진실. 우리는 항상 모든 곳에서 인터페이스를 사용하며 인터페이스는 비동기로 선언 될 수 없습니다. 따라서 Async 접미사 사용에 대한 공식 가이드는 완전히 말도 안되는 것 같습니다. 나는 async 키워드는 단지 구현 세부 사항, 메서드 내부의 일부이며 이름이나 외부에 영향을 미치지 않아야한다고 생각합니다.
Al Kepp

5

에서 비동기 및 비동기 프로그래밍 await를 (C #)를 , Microsoft는 다음과 같은 지침을 제공합니다 :

명명 규칙

규칙에 따라 async 한정 자가 있는 메서드 이름에 "Async"를 추가 합니다.

이벤트, 기본 클래스 또는 인터페이스 계약이 다른 이름을 제안하는 규칙을 무시할 수 있습니다. 예를 들어 일반적인 이벤트 처리기의 이름을 바꾸면 안됩니다 Button1_Click.

이 지침이 불완전하고 만족스럽지 않습니다. 이것은 async수정자가 없는 경우이 메서드 ConnectConnectAsync? 대신 이름을 지정해야 함 을 의미 합니까?

public Task<bool> ConnectAsync()
{
    return ConnectAsyncInternal();
}

나는 그렇게 생각하지 않는다. 에 나타난 바와 같이 간결하게 응답 하여 @Servy 및 더 자세한 대답 하여 @Luke Puplett , 나는 그것이 적절하고 실제로이 방법을 것으로 예상이라고 생각 한다 라는 이름ConnectAsync (그것이 awaitable을 반환하기 때문에). 이러한 상기 지지체에서 @ 존 스키트 에서 이 응답 다른 질문은 추가 Async상관없이 존재하는 방법 이름 async개질제.

마지막으로 다른 질문에대해 @Damien_The_Unbeliever의 의견 을 고려 하십시오 .

async/await이다 구현 하여 방법의 세부 사항. 그것은 당신의 방법을 선언 여부를 하나도 간단히 메모 중요한 async Task Method()단지 나 Task Method(), 지금까지로 발신자가 우려됩니다. (사실, 당신은 브레이킹 체인지로 간주되지 않고 나중에이 둘 사이를 자유롭게 변경할 수 있습니다.)

그로부터 이름을 지정하는 방법 을 지정하는 메서드비동기 적 특성 이라고 추론합니다 . 메서드 사용자는 async수정자가 구현에 사용 되는지 여부도 알지 못합니다 (C # 소스 코드 또는 CIL없이).

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