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

Swift Tasks(async/await)任务取消检查:为何代码未输出预期信息?

问题原因分析

你的代码无法打印取消相关内容,核心有两个关键问题:

1. 无限同步循环阻塞Task执行,无法响应取消

test()里的while true是无任何暂停的同步死循环,会永久占用Task的执行线程,导致Task根本没有机会检查自身的取消状态(Task.isCancelled)。Swift的Task取消是协作式的,需要任务在执行过程中主动让出线程(比如执行异步操作),才能处理取消请求、更新isCancelled状态。

这个死循环会一直运行,永远不会执行到if Task.isCancelled的判断逻辑,自然不会抛出错误,catch块也就不会被触发。

2. 抛出的错误类型不匹配

就算循环能退出,你抛出的是URLError(.badURL),而非CancellationError,所以catch里的if let cancellationError = error as? CancellationError永远不会成立,不会打印"Task canceled.."。

修正后的代码示例
import UIKit

class ViewController: UIViewController {
    
    private var task: Task<Void, Never>?
    
    override func viewDidLoad() {
        let task = Task {
            do {
                try await test()
            } catch {
                if Task.isCancelled {
                    print("cancelled in catch block..")
                }
                if let cancellationError = error as? CancellationError {
                    print("Task canceled..")
                }
            }
        }
        self.task = task
        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
            task.cancel()
        }
    }
    
    func test() async throws {
        while true {
            // 加入异步暂停,让Task有机会检查取消状态
            try await Task.sleep(nanoseconds: 500_000_000)
            
            if Task.isCancelled {
                print("cancelled..")
                // 抛出正确的CancellationError
                throw CancellationError()
            }
        }        
    }
}
关键修正点
  • 在循环中加入try await Task.sleep(...):让Task让出线程,有机会响应取消请求并更新isCancelled状态。
  • 抛出CancellationError:匹配catch块中的错误判断逻辑,触发对应的打印。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 21:33:14