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
相关产品推荐
相关产品推荐

