Swift结构化并发中addTask与addTaskUnlessCancelled的区别是什么?
问题根因:你的测试代码逻辑存在时序错误
你当前的示例中group.cancelAll()是在所有addTaskUnlessCancelled()调用完成之后才执行的,此时3个任务早已被提交到任务组中,自然都会打印added,测试逻辑无法验证两个方法的差异。
addTask()和addTaskUnlessCancelled()的核心区别
addTask(priority:operation:):无返回值,无条件向任务组提交任务。无论任务组当前是否已经被取消,任务都会被加入组内并进入调度执行队列。addTaskUnlessCancelled(priority:operation:):有布尔返回值,提交任务前会先检查任务组的取消状态:- 若任务组未被取消:任务正常加入组并进入调度,返回
true - 若任务组已被取消:任务会被直接丢弃,不会加入组也不会执行闭包逻辑,返回
false
- 若任务组未被取消:任务正常加入组并进入调度,返回
关于返回值的疑问
addTaskUnlessCancelled()的返回值和任务后续是否抛出错误完全无关,它仅代表「任务是否被成功加入到任务组」这一个行为的结果,和任务后续执行成功、失败、被取消都没有关联。
正确的测试示例
你可以调整cancel的时序来验证差异:
func testCancellation() async { await withThrowingTaskGroup(of: Void.self) { group in // 组未取消时提交,返回true,任务正常执行 let addResult1 = group.addTaskUnlessCancelled { print("任务1已添加") } print("任务1添加结果:\(addResult1)") // 输出true // 主动取消任务组 group.cancelAll() // 组已取消时提交,返回false,任务闭包不会执行 let addResult2 = group.addTaskUnlessCancelled { print("任务2已添加") // 该行永远不会打印 } print("任务2添加结果:\(addResult2)") // 输出false } }
补充说明
已经成功加入任务组的任务,在组调用cancelAll()后会被标记为取消状态,但任务是否真的终止运行取决于你是否在任务逻辑中实现了取消响应:系统自带的Task.sleep(nanoseconds:)等异步API会自动响应取消,自定义的耗时逻辑则需要主动检查Task.isCancelled状态做退出处理。
内容的提问来源于stack exchange,提问作者salman siddiqui
相关产品推荐
相关产品推荐

