连接两个取消令牌,而没有多余的取消令牌资源。

问题描述 投票:0回答:1

在一个获得 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();
    }
}
c# .net-core task-parallel-library cancellationtokensource
1个回答
2
投票

链接的取消源不是一种特殊的取消源。它是一个常规的取消源,也是与现有的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)。

© www.soinside.com 2019 - 2024. All rights reserved.