在 Dispose of Controller 中调用 cancellationToken.Cancel()?

Calling cancellationToken.Cancel() in Dispose of Controller?

我有控制器,我在构造函数中创建了一个 Cancellation Token 并在很长的 运行 await task () 中使用它。在 Controller.Dispose() 中处理取消标记是否会导致长 运行 任务取消?

public class SomeController : BaseInternalController
{
    private CancellationTokenSource cancellationTokenSource;

    public MyController()
    {
        cancellationTokenSource = new CancellationTokenSource();
    }

    public async Task<HttpResponseMessage> Post(SomeData data)
    {
        foreach (var item in data)
        {
            await longRunningTask(item, cancellationTokenSource.token);
        }

    }

    protected override void Dispose(bool disposing)
    {
        if (cancellationTokenSource != null)
        {
            cancellationTokenSource.Cancel();
            cancellationTokenSource.Dispose();
            cancellationTokenSource = null;
        }
        base.Dispose(disposing);
    }
}

Does disposing the Cancellation token in Controller.Dispose() causes the long running task to cancel?

取决于您的 longRunningTask 是如何实施的。 在此方法中,您应该明确检查是否请求取消:

token.ThrowIfCancellationRequested();

调用此方法后,您的任务将被取消。

取消示例

如果在下面的示例中 ThrowIfCancellationRequested 不会被调用,则任务将永远 运行:

var cts = new CancellationTokenSource();
Task.Run(() =>
{
    while (true)
        cts.Token.ThrowIfCancellationRequested();
}, cts.Token);

您可以了解有关取消的更多信息here


请注意,将 cancellationTokenSource 设置为 null 后,您可以在 foreach 循环中获得 NullReferenceException。我建议将您的令牌复制到局部变量中:

public async Task<HttpResponseMessage> Post(SomeData data)
{
    var token = cancellationTokenSource.Token;
    foreach (var item in data)
    {
        await longRunningTask(item, token);
    }
}