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

再次点击按钮时如何取消运行中的asyncio协程?

修复asyncio任务取消问题的方案

原代码无法正常取消任务的核心问题有三个,下面是针对性的修复方案:

关键问题分析

  1. 任务列表未持久化:创建任务时用了局部变量,取消分支根本访问不到正在运行的任务
  2. 阻塞UI事件循环:await asyncio.wait会让按钮回调一直等待到第一个任务完成,导致后续点击无法响应
  3. 未处理取消异常:任务被取消时会抛出CancelledError,未捕获会引发报错

修改后的完整代码

import asyncio
import flet as ft

class TasksManager:
    def __init__(self) -> None:
        self.state = False
        self.task_funcs = [self.task_1, self.task_2, self.task_3]
        self.tasks = []  # 用于保存正在运行的任务实例
 
    async def task_1(self):
        try:
            for i in range(10):
                await asyncio.sleep(1)
                print("Task 1: ", i)
        except asyncio.CancelledError:
            print("Task 1 已被取消")
    
    async def task_2(self):
        try:
            for i in range(10):
                await asyncio.sleep(1)
                print("Task 2: ", i)
        except asyncio.CancelledError:
            print("Task 2 已被取消")
 
    async def task_3(self):
        try:
            for i in range(10):
                await asyncio.sleep(1)
                print("Task 3: ", i)
        except asyncio.CancelledError:
            print("Task 3 已被取消")
 
    async def click(self, e: ft.TapEvent):
        if not self.state:
            self.state = True
            # 创建任务并保存到实例属性
            self.tasks = [asyncio.create_task(func()) for func in self.task_funcs]
            print("任务已启动")
        else:
            # 取消所有正在运行的任务
            for task in self.tasks:
                if not task.done():
                    task.cancel()
                    # 等待任务处理取消操作
                    await task
            self.state = False
            self.tasks.clear()
            print("所有任务已取消")
 
def main(page: ft.Page):
    manager = TasksManager()
    button = ft.TextButton("启动/取消任务", on_click=manager.click)
    page.add(button)
    page.update()
 
ft.app(main)

核心修改说明

  • 新增self.tasks实例属性,专门保存正在运行的任务对象,确保取消时能访问到
  • 移除await asyncio.wait,让任务在后台异步运行,不阻塞UI回调
  • 在每个任务内部添加try-except捕获CancelledError,处理取消逻辑并避免报错
  • 取消任务后调用await task,确保任务完成取消流程,然后重置state和任务列表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 05:35:09