CancellationToken的默认参数

我有一些asynchronous代码,我想添加CancellationToken。 然而,有很多不需要的实现,所以我想有一个默认参数 – 也许是CancellationToken.None。 然而,

Task<x> DoStuff(...., CancellationToken ct = null) 

产量

types''的值不能用作默认参数,因为没有标准转换来键入'System.Threading.CancellationToken'

 Task<x> DoStuff(...., CancellationToken ct = CancellationToken.None) 

“ct”的默认参数值必须是编译时常量

有没有什么办法来取消CancellationToken的默认值?

事实certificate,以下工作:

 Task<x> DoStuff(...., CancellationToken ct = default(CancellationToken)) 

有没有什么办法来取消CancellationToken的默认值?

不幸的是,这是不可能的,因为CancellationToken.None不是编译时间常量,这是可选参数中缺省值的要求。

但是,可以通过重载方法而不是尝试使用默认参数来提供相同的效果:

 Task<x> DoStuff(...., CancellationToken ct) { //... } Task<x> DoStuff(....) { return DoStuff(...., CancellationToken.None); } 

另一种select是使用Nullable<CancellationToken>参数,默认为null ,并在方法内部处理:

 Task<x> DoStuff(...., CancellationToken? ct = null) { var token = ct ?? CancellationToken.None; ... } 

这里有几个解决scheme,按照一般善良的顺序排列:

1.使用default(CancellationToken)作为默认值:

 Task DoAsync(CancellationToken ct = default(CancellationToken)) { … } 

在语义上, CancellationToken.None是默认的理想候选,但是不能这样使用,因为它不是一个编译时常量。 default(CancellationToken)是下一个最好的事情,因为它是一个编译时常量,并且正式logging为等效于CancellationToken.None

2.提供没有CancellationToken参数的方法重载:

或者,如果您更喜欢方法重载超过可选参数(请参阅此问题和关于该主题的这个问题):

 Task DoAsync(CancellationToken ct) { … } // actual method always requires a token Task DoAsync() => DoAsync(CancellationToken.None); // overload producing a default token 

对于接口方法,使用扩展方法可以达到相同的效果:

 interface IFoo { Task DoAsync(CancellationToken ct); } static class Foo { public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None); } 

这导致了一个更简洁的界面,并且使得实现者明确地写出转发方法的重载。

3.使参数为空,并使用null作为默认值:

 Task DoAsync(…, CancellationToken? ct = null) { … ct ?? CancellationToken.None … } 

我最不喜欢这个解决scheme,因为可空types会带来很小的运行时间开销,并且对取消标记的引用由于空合并运算符而变得更加冗长 。

Tofutim的回答是一种方式,但从评论我看到人们有问题。

在这种情况下,我确实build议可以有如下方法:

 Task<x> DoStuff(...., CancellationToken ct) { } 

并将其重载为:

 Task<x> DoStuff(....) { return DoStuff(...., CancellationToken.None); } 

这样编译,因为CancellationToken.None的值在编译时不需要。