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
的值在编译时不需要。