CancellationToken의 기본 매개 변수


96

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

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

수확량

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

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

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

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

답변:


151

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

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

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

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


4
이것은 정확히 프레임 워크는 현재 수행 내부적으로,하지만 난 할 수 없습니다 내 코드에서 그것을 할. 마이크로 소프트는 자신의 구현을 변경하는 경우 코드와 어떻게, 어떤 생각 CancellationToken.None뭔가 이상이된다 default(CancellationToken).
noseratio

10
@Noseratio 그것은 이전 버전과의 호환성을 크게 깨뜨릴 것이기 때문에 그런 일이 일어날 것이라고 기대하지 않습니다. 그리고 또 무엇을 default(CancellationToken)할까요?
svick

3
@Noseratio : 당신은 너무 경직되고 있습니다. 기회는 CancellationToken.None사실상 더 이상 사용되지 않을 것입니다. Microsoft조차도 default(CancellationToken)대신 사용 하고 있습니다. 예를 들어 Entity Framework의 소스 코드에서 이러한 검색 결과 를 참조하십시오 .
drowa

21
MSDN CancellationToken.None 속성에서 : "C # default (CancellationToken) 문을 사용하여 빈 취소 토큰을 만들 수도 있습니다 . " . 미래 버전의 C #에서 기본 매개 변수로 받아들이 기 전까지는 오류가 없습니다.
MuiBienCarlota

5
여기에서 동일 함 누락 된 두 중간 조합을 보완하기 위해 개발자는 cancelToken 매개 변수에 대해 None 또는 기본 CancellationToken을 전달하고 progress 매개 변수에 대해 null을 전달할 수 있습니다.
Arek Bal

25

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

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

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

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

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

6
MSDN 의 Task-based Asynchronous Pattern 문서 (특히 Choosing the Overloads to Provide 섹션에서 설명)에 설명 된대로이 문제를 처리하는 데 권장되는 방법 입니다.
Sam Harwell 2014 년

CancellationToken.None == 기본값 true
eoleary

5
무슨 일이야 CancellationToken cancellationToken = default(CancellationToken)? 여기에서도 설명 됨 blogs.msdn.microsoft.com/andrewarnottms/2014/03/19/…
Ray

20

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

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 병합 연산자 때문에 취소 토큰에 대한 참조가 더 장황 해지기 때문에이 솔루션이 가장 마음에 듭니다 ??.


11

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

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

훌륭한! 에 의해 현재까지 가장 좋은 대답은
존 헨켈

4

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

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

-1

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

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

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

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

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

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

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