[c#] CancellationToken의 기본 매개 변수

추가하고 싶은 비동기 코드가 있습니다 CancellationToken. 그러나 이것이 필요하지 않은 많은 구현이 있으므로 기본 매개 변수를 갖고 싶습니다 CancellationToken.None. 하나,

Task<x> DoStuff(...., CancellationToken ct = null)

수확량

‘System.Threading.CancellationToken’유형에 대한 표준 변환이 없기 때문에 ”유형의 값을 기본 매개 변수로 사용할 수 없습니다.

Task<x> DoStuff(...., CancellationToken ct = CancellationToken.None)

‘ct’의 기본 매개 변수 값은 컴파일 타임 상수 여야합니다.

에 대한 기본값을 가질 수있는 방법이 CancellationToken있습니까?



답변

다음이 작동하는 것으로 밝혀졌습니다.

Task<x> DoStuff(...., CancellationToken ct = default(CancellationToken))

이는 문서에 따르면 , 동일로 해석됩니다 CancellationToken.None:

C # default(CancellationToken)문을 사용하여 빈 취소 토큰을 만들 수도 있습니다 .


답변

CancellationToken에 대한 기본값을 가질 수있는 방법이 있습니까?

안타깝게도 CancellationToken.None선택 인수의 기본값에 대한 요구 사항 인 컴파일 시간 상수가 아니기 때문에 이것은 불가능합니다.

그러나 기본 매개 변수를 사용하는 대신 오버로드 된 메서드를 만들어 동일한 효과를 제공 할 수 있습니다.

Task<x> DoStuff(...., CancellationToken ct)
{
    //...
}

Task<x> DoStuff(....)
{
    return DoStuff(...., CancellationToken.None);
}


답변

다음은 일반적인 장점의 내림차순으로 몇 가지 솔루션입니다.

1. default(CancellationToken)기본값으로 사용 :

Task DoAsync(CancellationToken ct = default(CancellationToken)) {  }

의미 론적으로 CancellationToken.None는 기본값에 대한 이상적인 후보이지만 컴파일 시간 상수가 아니기 때문에 사용할 수 없습니다. default(CancellationToken)컴파일 시간 상수이고 공식적으로CancellationToken.None .

2. CancellationToken매개 변수 없이 메소드 오버로드 제공 :

당신이 선택적 매개 변수를 통해 메서드 오버로드를 선호하는 경우 또는 (볼 그 주제에 대한 질문에) :

Task DoAsync(CancellationToken ct) {  } // actual method always requires a token
Task DoAsync() => DoAsync(CancellationToken.None); // overload producing a default token

인터페이스 메서드의 경우 확장 메서드를 사용하여 동일한 결과를 얻을 수 있습니다.

interface IFoo
{
    Task DoAsync(CancellationToken ct);
}

static class Foo
{
    public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None);
}

이로 인해 인터페이스가 더 얇아지고 구현자가 전달 메서드 오버로드를 명시 적으로 작성하지 않아도됩니다.

3. 매개 변수를 nullable로 만들고 null기본값으로 사용 :

Task DoAsync(…, CancellationToken? ct = null)
{
     ct ?? CancellationToken.None 
}

nullable 형식에는 런타임 오버 헤드가 적고 null 병합 연산자 때문에 취소 토큰에 대한 참조가 더 장황 해지기 때문에이 솔루션이 가장 마음에 듭니다 ??.


답변

또 다른 옵션은 Nullable<CancellationToken>매개 변수 를 사용하고 기본값을로 설정 한 null다음 메서드 내에서 처리하는 것입니다.

Task<x> DoStuff(...., CancellationToken? ct = null) {
    var token = ct ?? CancellationToken.None;
    ...
}


답변

최신 버전의 C #에서는 기본 (CancellationToken) 버전에 대한 간단한 구문을 사용할 수 있습니다. 예 :

Task<x> DoStuff(...., CancellationToken ct = default)


답변

Tofutim의 대답 은 한 가지 방법이지만 의견을 보면 사람들이 문제가 있음을 알 수 있습니다.

이 경우 다음과 같은 방법을 가질 수 있다고 제안했습니다.

Task<x> DoStuff(...., CancellationToken ct)
{
} 

다음과 같이 과부하하십시오.

Task<x> DoStuff(....)
{
    return DoStuff(...., CancellationToken.None);
}

CancellationToken.None컴파일 타임에 의 값이 필요하지 않기 때문에 컴파일됩니다.


답변