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

C#中如何取消MDI子窗体中的异步任务?

如何在窗体卸载或点击取消按钮时取消后台任务

要实现任务取消,核心是用CancellationTokenSource和CancellationToken,这是.NET中任务取消的标准协作式方案,步骤如下:

1. 声明取消令牌源字段

在你的MDI子窗体类中添加一个CancellationTokenSource字段,用来跨方法管理取消信号:

private CancellationTokenSource _cts;

2. 修改任务方法,支持取消

更新BuscaActualizaciones和DoLongThing方法,传入取消令牌,并在耗时操作中定期检查取消请求:

private async void BuscaActualizaciones()
{
    try
    {
        // 将取消令牌传递给Task.Run和耗时方法
        await Task.Run(() => DoLongThing(_cts.Token), _cts.Token);
    }
    catch (OperationCanceledException)
    {
        // 任务被取消时的自定义处理,比如提示用户
        MessageBox.Show("任务已取消");
    }
}

private void DoLongThing(CancellationToken token)
{
    // 你的耗时操作逻辑,需要在关键节点检查取消信号
    // 示例:模拟循环执行的耗时任务
    for (int i = 0; i < 100; i++)
    {
        // 检查是否收到取消请求,若有则抛出异常终止任务
        token.ThrowIfCancellationRequested();
        
        // 这里替换成你的实际耗时代码
        System.Threading.Thread.Sleep(100);
    }
}

3. 启动任务时初始化取消令牌源

修改搜索按钮的点击事件,每次启动新任务前先清理旧的令牌源,避免冲突:

private void BtnBuscar_Click(object sender, EventArgs e)
{
    // 若之前有任务在运行,先取消并释放资源
    _cts?.Cancel();
    _cts?.Dispose();
    
    // 创建新的取消令牌源
    _cts = new CancellationTokenSource();
    
    // 启动任务
    BuscaActualizaciones();
}

4. 实现取消按钮逻辑

添加取消按钮的点击事件,触发任务取消:

private void BtnCancelar_Click(object sender, EventArgs e)
{
    // 发送取消信号
    _cts?.Cancel();
}

5. 窗体卸载时清理任务

在窗体的FormClosing事件中处理取消,确保窗体关闭时任务停止并释放资源:

private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
    _cts?.Cancel();
    _cts?.Dispose();
}

关键说明

  • 任务取消是协作式的:必须在DoLongThing的耗时操作中定期调用token.ThrowIfCancellationRequested(),否则任务不会主动停止。如果你的耗时操作是单次调用的外部方法,需要看该方法是否支持传入CancellationToken。
  • 每次启动新任务前必须清理旧的CancellationTokenSource,否则会导致旧任务的取消信号干扰新任务。
  • OperationCanceledException是任务取消时的正常异常,捕获后可以做友好提示或清理工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:25:35