추가하고 싶은 비동기 코드가 있습니다 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
컴파일 타임에 의 값이 필요하지 않기 때문에 컴파일됩니다.