以下是按一般善意降序排列的几种解决方案:
1. default(CancellationToken)
用作默认值:
Task DoAsync(CancellationToken ct = default(CancellationToken)) { … }
从语义上讲,CancellationToken.None
它将是默认值的理想候选者,但不能这样使用,因为它不是编译时常量。default(CancellationToken)
其次是最好的事情,因为它是一个编译时常量,并且正式证明与等效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 …
}
我之所以喜欢这种解决方案,至少是因为可空类型带有较小的运行时开销,并且由于空合并运算符,对取消令牌的引用变得更加冗长??
。
CancellationToken.None
不仅仅是default(CancellationToken)
。