在一个获得 CancellationToken
(StartAsync
)我想增加一个内部的 CancellationToken
所以异步操作可以被调用者从外部或内部取消(例如通过调用一个叫 AbortAsync()
方法)。)
AFAIK,做这件事的方法是使用 CreateLinkedCancellationTokenSource
. 但它的API似乎相当不舒服,因为我需要创建 两种 附加 CancellationTokenSource
实例,并且因为他们实现了 IDisposable
我也不能忘记处理它们。因此,我需要把它们都作为成员储存起来,以便日后处理。
我是不是遗漏了什么?我觉得应该有一种更简单的方法,将额外的取消机制附加到现有的令牌上,而不是强迫我维护两个令牌。CancellationTokenSource
实例。
public Task StartAsync(CancellationToken externalToken)
{
this.actualCancellation = new CancellationTokenSource();
this.linkedCancellation = CancellationTokenSource.CreateLinkedTokenSource(
actualCancellation.Token, externalToken);
this.execution = this.ExecuteAsync(this.linkedCancellation.Token);
return this.execution;
}
public async Task AbortAsync()
{
try
{
this.actualCancellation.Cancel();
await this.execution;
}
catch
{
}
finally
{
this.actualCancellation.Dispose();
this.linkedCancellation.Dispose();
}
}
链接的取消源不是一种特殊的取消源。它是一个常规的取消源,也是与现有的token "链接 "的--也就是说,当现有的token被取消时,该源将被取消。在所有其他方面,它都是一个普通的取消源,因此您可以像其他取消源一样自行取消它。
因此,您只需要一个取消源--一个与现有令牌相连的取消源。和 也可以手动取消。
public Task StartAsync(CancellationToken externalToken)
{
this.linkedCancellation = CancellationTokenSource.CreateLinkedTokenSource(externalToken);
this.execution = this.ExecuteAsync(this.linkedCancellation.Token);
return this.execution;
}
public async Task AbortAsync()
{
try
{
this.linkedCancellation.Cancel();
await this.execution;
}
catch
{
}
finally
{
this.linkedCancellation.Dipose();
}
}
我想说的是,我会仔细考虑这种API设计的寿命问题。目前的 StartAsync
做资源分配和 AbortAsync
做清理工作;我建议设计一个由构造函数和 Dispose
(RAII)。