swiftasync-awaitcontinuationsstructured-concurrency

How to resume a continuation ensuring that the result is delivered on the MainActor?


I have a continuation:

func a() async -> Int {
    await withCheckedContinuation { continuation in
        continuation.resume(returning: 3)
    }
}

I would like all callers of this function to receive the result on the MainActor. I wouldn't like the caller to have to explicitly specify this rescheduling. I don't want this:

func c() async {
    let three = await a()
    await MainActor.run {
        b(three)
    }
}

What I instead want is for the entire code after returning to be performed on the MainThread until the next suspension point, something like this:

func c1() async {
    let three = await a()

    b(three) // Guaranteed main thread, although nothing speaks of it here
}

In a way, I want a to declare that I return only on main actor!, like this:

func a() @MainActor async -> Int {
    await withCheckedContinuation { continuation in
        continuation.resume(returning: 3)
    }
}

Is there any way to even do this?

UPDATE: Both commenters have suggested that I annotate the enclosing functions c and c1 with @MainActor.

@MainActor
func c() async {
    let three = await a()
    await MainActor.run {
       b(three)
    }
}

This doesn't do it like I need it. It says:

But what I need instead is this:


Solution

  • No, there is no way to do this.

    If you await some function, you can decide on which thread will it return. But being an await-able function, you can not make sure that your result will be delivered to the caller on a particular and/or main thread.