Voici plusieurs solutions, par ordre décroissant de bonté générale:
1. En utilisant default(CancellationToken)
comme valeur par défaut:
Task DoAsync(CancellationToken ct = default(CancellationToken)) { … }
Sémantiquement, CancellationToken.None
serait le candidat idéal pour la valeur par défaut, mais ne peut pas être utilisé en tant que tel car ce n'est pas une constante de compilation. default(CancellationToken)
est la prochaine meilleure chose car il s'agit d'une constante de compilation et officiellement documentée comme équivalente àCancellationToken.None
.
2. Fournir une surcharge de méthode sans CancellationToken
paramètre:
Ou, si vous préférez les surcharges de méthode aux paramètres facultatifs (voir ceci et cette question sur ce sujet):
Task DoAsync(CancellationToken ct) { … } // actual method always requires a token
Task DoAsync() => DoAsync(CancellationToken.None); // overload producing a default token
Pour les méthodes d'interface, la même chose peut être obtenue en utilisant des méthodes d'extension:
interface IFoo
{
Task DoAsync(CancellationToken ct);
}
static class Foo
{
public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None);
}
Cela se traduit par une interface plus mince et évite aux implémenteurs d'écrire explicitement la surcharge de la méthode de transfert.
3. Rendre le paramètre nullable et utiliser null
comme valeur par défaut:
Task DoAsync(…, CancellationToken? ct = null)
{
… ct ?? CancellationToken.None …
}
J'aime moins cette solution parce que les types Nullable sont livrés avec une petite surcharge d'exécution, et les références au jeton d'annulation deviennent plus verbeuses en raison de l'opérateur de fusion null ??
.
CancellationToken.None
devient quelque chose de plus quedefault(CancellationToken)
.