You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何中止已跟踪的Task任务?

解决方案

核心前提

.NET 中不存在安全强制中止Task的 API,所有任务取消都遵循协作式取消机制,必须配合CancellationToken(取消令牌)实现。你现有代码仅存储Task对象无法完成中止操作,需要按以下步骤调整:


步骤1:修改TrackedProgress类,关联取消令牌源

新增CancellationTokenSource字段存储对应任务的取消控制器:

public sealed class TrackedProgress
{
    internal DateTime StartedAt { get; set; }
    public Task Job { get; set; }
    public int? Duration { get; set; }
    // 新增:关联任务的取消源
    internal CancellationTokenSource Cts { get; set; }

    public TrackedProgress(Task job, CancellationTokenSource cts)
    {
        StartedAt = DateTime.Now;
        Job = job;
        Cts = cts;
    }

    public TrackedProgress(DateTime startedAt, Task job, CancellationTokenSource cts)
    {
        StartedAt = startedAt;
        Job = job;
        Cts = cts;
    }
}

步骤2:调整ProgressTracker的TryStart方法

修改方法签名,要求传入可接收取消令牌的任务委托,内部自动创建取消令牌源绑定到任务:

public bool TryStart(string name, Func<CancellationToken, Task> taskFactory)
{
    if (string.IsNullOrWhiteSpace(name))
    {
        throw new ArgumentNullException(nameof(name));
    }
    if (taskFactory == null)
    {
        throw new ArgumentNullException(nameof(taskFactory));
    }

    // 为每个任务创建独立的取消源
    var cts = new CancellationTokenSource();
    var task = taskFactory(cts.Token);
    return _tracker.TryAdd(name, new TrackedProgress(task, cts));
}

如果要兼容原有传入Task的调用方式,你需要要求调用方自行将CancellationToken传入任务,同时在调用TryStart时额外传入对应的CancellationTokenSource参数即可。


步骤3:实现TryAbort取消逻辑

调用对应取消源的Cancel方法触发任务取消,完成后释放资源:

public bool TryAbort(string name, out int? duration)
{
    duration = null;
    if (_tracker.TryRemove(name, out TrackedProgress progress))
    {
        if(!progress.Job.IsCanceled && !progress.Job.IsCompleted)
        {
            // 触发取消信号
            progress.Cts.Cancel();
            // 可选:等待任务完成取消流程再释放
            // progress.Job.Wait(1000);
            // 释放取消源资源
            progress.Cts.Dispose();
        }
        duration = (int)DateTime.Now.Subtract(progress.StartedAt).TotalSeconds;
        return true;
    }
    return false;
}

步骤4:任务实现侧要求

你自己编写的任务逻辑必须主动监听取消令牌,否则取消信号不会生效,示例任务写法:

// 示例:支持取消的任务逻辑
async Task MyTaskLogic(CancellationToken token)
{
    for(int i=0; i<100; i++)
    {
        // 监听取消信号,收到信号会抛出OperationCanceledException结束任务
        token.ThrowIfCancellationRequested();
        // 也可以主动判断后优雅退出
        // if(token.IsCancellationRequested) return;
        await Task.Delay(1000, token);
    }
}

// 调用TryStart传入任务
tracker.TryStart("task1", MyTaskLogic);

注意:不要使用Thread.Abort这类强制中止线程的API,这类方法会导致进程状态不稳定、资源泄漏,.NET Core+版本中已经不支持该方法。

内容的提问来源于stack exchange,提问作者Jay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 18:06:04