I have some async code that I would like to add a CancellationToken
to. However, there are many implementations where this is not needed so I would like to have a d
It turns out that the following works:
Task<x> DoStuff(...., CancellationToken ct = default(CancellationToken))
...or:
Task<x> DoStuff(...., CancellationToken ct = default) // C# 7.1 and later
which, according to the documentation, is interpreted the same as CancellationToken.None
:
You can also use the C#
default(CancellationToken)
statement to create an empty cancellation token.
Another option is to use a Nullable<CancellationToken>
parameter, default it to null
, and deal with it inside the method:
Task<x> DoStuff(...., CancellationToken? ct = null) {
var token = ct ?? CancellationToken.None;
...
}
Newer versions of C# allow for a simplified syntax for the default(CancellationToken) version. E.g.:
Task<x> DoStuff(...., CancellationToken ct = default)
Tofutim's answer is one way, but from the comments I see that people have issues with it.
In that case, I did suggest that one can have a method as follows:
Task<x> DoStuff(...., CancellationToken ct)
{
}
and overload it as:
Task<x> DoStuff(....)
{
return DoStuff(...., CancellationToken.None);
}
This compiles, because the value of CancellationToken.None
is not required at compile time.
Here are several solutions, in descending order of general goodness:
default(CancellationToken)
as default value:Task DoAsync(CancellationToken ct = default(CancellationToken)) { … }
Semantically, CancellationToken.None
would be the ideal candidate for the default, but cannot be used as such because it isn't a compile-time constant. default(CancellationToken)
is the next best thing because it is a compile-time constant and officially documented to be equivalent to CancellationToken.None.
CancellationToken
parameter:Or, if you prefer method overloads over optional parameters (see this and this question on that topic):
Task DoAsync(CancellationToken ct) { … } // actual method always requires a token
Task DoAsync() => DoAsync(CancellationToken.None); // overload producing a default token
For interface methods, the same can be achieved using extension methods:
interface IFoo
{
Task DoAsync(CancellationToken ct);
}
static class Foo
{
public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None);
}
This results in a slimmer interface and spares implementers from explicitly writing the forwarding method overload.
null
as default value:Task DoAsync(…, CancellationToken? ct = null)
{
… ct ?? CancellationToken.None …
}
I like this solution least because nullable types come with a small runtime overhead, and references to the cancellation token become more verbose because of the null coalescing operator ??
.
Is there any way to have a default value for CancellationToken?
Unfortunately, this is not possible, as CancellationToken.None
is not a compile time constant, which is a requirement for default values in optional arguments.
You can provide the same effect, however, by making an overloaded method instead of trying to use default parameters:
Task<x> DoStuff(...., CancellationToken ct)
{
//...
}
Task<x> DoStuff(....)
{
return DoStuff(...., CancellationToken.None);
}