J'ai du code asynchrone auquel j'aimerais ajouter un CancellationToken. Cependant, il existe de nombreuses implémentations où cela n'est pas nécessaire, donc je voudrais avoir un paramètre par défaut - peut-être CancellationToken.None. cependant,
Task<x> DoStuff(...., CancellationToken ct = null)
les rendements
Une valeur de type "" ne peut pas être utilisée comme paramètre par défaut car il n'y a pas de conversions standard pour taper "System.Threading.CancellationToken"
et
Task<x> DoStuff(...., CancellationToken ct = CancellationToken.None)
La valeur de paramètre par défaut pour 'ct' doit être une constante de temps de compilation
Existe-t-il un moyen d'avoir une valeur par défaut pour CancellationToken?
Il s'avère que les travaux suivants:
Task<x> DoStuff(...., CancellationToken ct = default(CancellationToken))
qui, selon la documentation , est interprété de la même façon que CancellationToken.None
:
Vous pouvez également utiliser l'instruction C #
default(CancellationToken)
pour créer un jeton d'annulation vide.
Existe-t-il un moyen d'avoir une valeur par défaut pour CancellationToken?
Malheureusement, ce n'est pas possible, car CancellationToken.None
n'est pas une constante de temps de compilation, ce qui est une exigence pour les valeurs par défaut dans les arguments facultatifs.
Vous pouvez cependant fournir le même effet en créant une méthode surchargée au lieu d'essayer d'utiliser les paramètres par défaut:
Task<x> DoStuff(...., CancellationToken ct)
{
//...
}
Task<x> DoStuff(....)
{
return DoStuff(...., CancellationToken.None);
}
Voici plusieurs solutions, par ordre décroissant de bonté générale:
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é tel quel car il ne s'agit pas d'une constante de temps de compilation. default(CancellationToken)
est la prochaine meilleure chose car c'est une constante de temps de compilation et officiellement documenté pour être équivalent à CancellationToken.None
.
CancellationToken
:Ou, si vous préférez les surcharges de méthode aux paramètres facultatifs (voir this et this 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.
null
comme valeur par défaut:Task DoAsync(…, CancellationToken? ct = null)
{
… ct ?? CancellationToken.None …
}
J'aime moins cette solution car les types nullables 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 coalescence nul ??
.
Une autre option consiste à utiliser un Nullable<CancellationToken>
paramètre, définissez-le par défaut sur null
, et traitez-le dans la méthode:
Task<x> DoStuff(...., CancellationToken? ct = null) {
var token = ct ?? CancellationToken.None;
...
}