Suspending/resuming multiple tasks by using continuations

Here is the revised version using the AsyncStream.

func suspendResumeTasks (M: Int = 5) async throws {
    let chan = Channel <CheckedContinuation <Void, Never>> ()
    
    for i in 0..<M {
        Task {
            await withCheckedContinuation {
                chan.send ($0)
                print ("\(i) suspending")
            }
            print ("\(i) resumed")
        }
    }

    var n = 0
    for await cont in chan.stream {
        cont.resume()
        n += 1
        if n == M {
            break
        }
    }
}

struct Channel <T>: Sendable where T:Sendable {
    let stream : AsyncStream <T>
    let cont   : AsyncStream <T>.Continuation
    
    init () {
        let u = Self.makeStreamAndCont ()
        self.stream = u.0
        self.cont   = u.1
    }
    
    func send (_ u: T?) {
        if let u {
            cont.yield(u)
        }
        else {
            cont.finish()
        }
    }
    
    static func makeStreamAndCont () -> (AsyncStream <T>, AsyncStream <T>.Continuation) {
        let t = AsyncStream <T>.makeStream()
        return t
    }
}

1 Like