Hier sind mehrere Lösungen in absteigender Reihenfolge der allgemeinen Güte:
1. default(CancellationToken)
Als Standardwert verwenden:
Task DoAsync(CancellationToken ct = default(CancellationToken)) { … }
Semantisch CancellationToken.None
wäre dies der ideale Kandidat für die Standardeinstellung, kann jedoch nicht als solcher verwendet werden, da es sich nicht um eine Konstante für die Kompilierungszeit handelt. default(CancellationToken)
ist das nächstbeste, da es sich um eine Konstante zur Kompilierungszeit handelt, die offiziell als gleichwertig dokumentiert istCancellationToken.None
.
2. Bereitstellung einer Methodenüberladung ohne CancellationToken
Parameter:
Oder wenn Sie Methodenüberladungen gegenüber optionalen Parametern bevorzugen (siehe diese und diese Frage zu diesem Thema):
Task DoAsync(CancellationToken ct) { … } // actual method always requires a token
Task DoAsync() => DoAsync(CancellationToken.None); // overload producing a default token
Für Schnittstellenmethoden kann dasselbe mit Erweiterungsmethoden erreicht werden:
interface IFoo
{
Task DoAsync(CancellationToken ct);
}
static class Foo
{
public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None);
}
Dies führt zu einer schlankeren Benutzeroberfläche und erspart Implementierern das explizite Schreiben der Überladung der Weiterleitungsmethode.
3. Den Parameter auf Null setzen und null
als Standardwert verwenden:
Task DoAsync(…, CancellationToken? ct = null)
{
… ct ?? CancellationToken.None …
}
Diese Lösung gefällt mir am wenigsten, weil nullfähige Typen mit einem geringen Laufzeitaufwand verbunden sind und Verweise auf das Lösch-Token aufgrund des Null-Koaleszenz-Operators ausführlicher werden ??
.
CancellationToken.None
etwas mehr als wirddefault(CancellationToken)
.