Default parameter for CancellationToken
Solution 1
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.
Solution 2
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);
}
Solution 3
Here are several solutions, in descending order of general goodness:
1. Using 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
.
2. Providing a method overload without a 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.
3. Making the parameter nullable and using 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 ??
.
Solution 4
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;
...
}
Solution 5
Newer versions of C# allow for a simplified syntax for the default(CancellationToken) version. E.g.:
Task<x> DoStuff(...., CancellationToken ct = default)
tofutim
Updated on August 23, 2022Comments
-
tofutim over 1 year
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 default parameter - perhapsCancellationToken.None
. However,Task<x> DoStuff(...., CancellationToken ct = null)
yields
A value of type '<null>' cannot be used as a default parameter because there are no standard conversions to type 'System.Threading.CancellationToken'
and
Task<x> DoStuff(...., CancellationToken ct = CancellationToken.None)
Default parameter value for 'ct' must be a compile-time constant
Is there any way to have a default value for
CancellationToken
?-
Palec almost 3 yearsI've also seen
new CancellationToken()
which is exactly equivalent todefault
as CancellationToken is a struct.
-
-
Sam Harwell about 10 yearsThis is the recommended way to handle this, as explained on the Task-based Asynchronous Pattern documentation on MSDN (specifically in the section Choosing the Overloads to Provide).
-
noseratio about 10 yearsThis is exactly what the framework currently does internally, but I would not do it in my code. Think what happens with your code if Microsoft change their implementation, and
CancellationToken.None
becomes something more thandefault(CancellationToken)
. -
svick about 10 years@Noseratio That would break backwards compatibility in a big way, so I wouldn't expect that to happen. And what else would
default(CancellationToken)
do? -
noseratio about 10 years@svick, if my library references
System.Threading.CancellationToken.None
property, and the value ofCancellationToken.None
changes in a future version of mscorlib.dll, how would that break my library (the IL code)? I would not make predictions aboutdefault(CancellationToken)
though. -
svick about 10 years@Noseratio If your library uses
default(CancellationToken)
(ornew CancellationToken()
), which I think is a valid thing to do for any value type, and that value started behaving differently, then that would break compatibility. -
noseratio about 10 years@svick, I see your point, but nowhere on MSDN it is mentioned that
CancellationToken.None
is the same thing asdefault(CancellationToken)
. Technically it may become astatic readonly
struct with non-default fields, unlikely but possible. Then if my library usedCancellationToken.None
, I'd stay compatible. Not so if it useddefault(CancellationToken)
. -
drowa about 9 years@Noseratio: You're being too rigid. Chances are
CancellationToken.None
will become de facto deprecated. Even Microsoft is usingdefault(CancellationToken)
instead. For example, see these search results from the source code of the Entity Framework. -
noseratio about 9 years@drowa, peace here.
CancellationToken.None
is unlikely to be deprecated, but I've been using myselfdefault(CancellationToken)
since then :) Plus to the OP. -
MuiBienCarlota almost 9 yearsFrom MSDN CancellationToken.None Property: "You can also use the C# default(CancellationToken) statement to create an empty cancellation token". None is a mistake until a futur version of C# accept it as default parameter.
-
Arek Bal over 8 yearsSame here To compensate for the two missing intermediate combinations, developers may pass None or a default CancellationToken for the cancellationToken parameter and null for the progress parameter.
-
eoleary about 6 yearsCancellationToken.None == default true
-
Syroot about 6 yearsWhat's the matter with
CancellationToken cancellationToken = default(CancellationToken)
? Also described here blogs.msdn.microsoft.com/andrewarnottms/2014/03/19/… -
John Henckel almost 5 yearsbrilliant! by far this is the best answer