GitHub code size in bytes GitHub build results

Swift 并发 ‘gate’ 类型,用于控制异步任务的前进进度。

门可以被打开和关闭,当门关闭时,无法进入。异步任务可以在其执行过程中的适当点(由它们选择,例如检查任务取消)穿过门。如果在它们尝试进入门时门是关闭的,它们将暂停并等待门打开后再继续。

门可以从任何代码(不仅仅是异步上下文)打开或关闭。

一个示例用法是在 SwiftUI 中,您有后台任务(例如,来自 task 视图修饰符),您希望暂停和恢复以响应状态更改

struct Example: View {
    let frames: NSImage

    @Binding var animate: Bool {
        didSet {
            guard animate != oldValue else { return }

            if animate {
                self.animationGate.open()
            } else {
                self.animationGate.close()
            }
        }
    }
    
    @State private var animationGate = Gate(initiallyOpen: true)

    @State var currentFrameIndex: Int = 0
    
    var body: some View {
        Image(nsImage: self.frames[self.currentFrameIndex])
            .task {
                while let _ = try? await self.animationGate.enter() {
                    self.currentFrameIndex = (self.currentFrameIndex + 1) % self.frames.count
                    try? await Task.sleep(for: .seconds(1) / 60)
                }
            }
    }
}

请注意,如果任务被取消,enter 总是会抛出错误,因此,如果您像上面的示例中那样使用 Gate 进入,则无需手动检查取消(例如,Task.checkCancellation / Task.isCancelled)。

感谢…

这受到(并且部分基于)Gwendal RouéSemaphore 包的启发。