互斥取消Tasks:寻求更简洁的异步实现方案
更简洁的实现方案
你可以利用Swift的TaskGroup来实现这个逻辑,它天然支持并发任务的竞争场景,代码更简洁优雅,不需要手动管理两个任务的引用和互相取消的逻辑:
func startTest() async throws { Task { await test() } try await Task.sleep(nanoseconds: 1 * NSEC_PER_SEC) // comment out this next line to test the timeout NotificationCenter.default.post(name: .init("Test"), object: nil) } func test() async { await withTaskGroup(of: Void.self) { group in // 添加等待通知的任务 group.addTask { for await _ in NotificationCenter.default .notifications(named: .init("Test"), object: nil) .prefix(1) {} print("Done waiting for the notification") } // 添加超时任务 group.addTask { try? await Task.sleep(nanoseconds: 5 * NSEC_PER_SEC) print("I timed out and cancelled the notification task") } // 等待第一个完成的任务 _ = await group.next() // 取消所有未完成的任务 group.cancelAll() } print("finished!") }
方案优势
- 无需手动持有两个
Task的引用,TaskGroup会自动管理所有子任务 group.next()会直接返回第一个完成的任务结果,天然实现"先完成者胜出"的逻辑group.cancelAll()会自动取消所有未完成的子任务,不用手动调用单个任务的cancel()方法- 代码结构更紧凑,符合Swift并发框架的设计理念
如果需要处理任务的返回值或错误,只需要调整TaskGroup的泛型参数(比如of: Result<Void, Error>.self),并在next()后处理对应结果即可。
内容的提问来源于stack exchange,提问作者matt
相关产品推荐
相关产品推荐

