这个班级CancellationTokenSource是一次性的.快速浏览Reflector证明KernelEvent了(很可能)非托管资源的使用.由于CancellationTokenSource没有终结器,如果我们不处理它,GC将不会这样做.
另一方面,如果您查看MSDN文章" 托管线程中的取消"中列出的示例,则只有一个代码段处置该令牌.
在代码中处理它的正确方法是什么?
using如果您不等待它,则无法将启动并行任务的代码包装起来.只有在你不等的时候取消才有意义.ContinueWith通过Dispose电话添加任务,但这是要走的路吗?.ForAll(x => Console.Write(x))?因为它没有类似于Reset清理IsCancelRequested和Token字段的方法,所以我认为它不可重复使用,因此每次启动任务(或PLINQ查询)时都应该创建一个新任务.这是真的吗?如果是,我的问题是Dispose在这些CancellationTokenSource案例中处理的正确和建议的策略是什么?
在获取CancellationToken( StartAsync) 的方法内部,我想添加一个内部函数CancellationToken,以便调用者可以在外部或内部取消异步操作(例如,通过调用方法AbortAsync())。
AFAIK,这样做的方法是使用CreateLinkedCancellationTokenSource. 但它的 API 似乎相当不舒服,因为我需要为此创建两个额外的实例,并且因为它们实现了,所以我也必须不要忘记处置它们。因此,我需要将它们都存储为成员以供以后处理。CancellationTokenSourceIDisposable
我错过了什么吗?我觉得应该有一种更简单的方法来将额外的取消机制附加到现有令牌上,而不会迫使我维护两个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();
}
}
Run Code Online (Sandbox Code Playgroud)