Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - async/await - Execute async method on background thread from MainActor Task

Here's my viewDidLoad method :

func viewDidLoad() {
    // Stuff here
    Task { @MainActor in 
        doSomeWorkOnMainThread1()
        doSomeWorkOnMainThread2()

        await doSomeBackgroundWork()

        doSomeWorkOnMainThread3()
        doSomeWorkOnMainThread4()
    }
}

And here's my method that should execute work on a background thread :

func doSomeBackgroundWork() async {
    // can add some code here
    // long image processing task
    assert(!Thread.isMainThread)
    // can add some code here
}

Is it possible to execute doSomeBackgroundWork on a background thread (without using GCD), and wait for it before going back to the main thread ?

like image 601
Xys Avatar asked Oct 19 '25 09:10

Xys


1 Answers

You are looking for Task.sleep. Note that it is in nanoseconds which is Really Weird, so I have written an extension to switch to seconds; to get it, you must use a Double, not an Int:

extension Task where Success == Never, Failure == Never {
    static func sleep(_ seconds:Double) async {
        await self.sleep(UInt64(seconds * 1_000_000_000))
    }
    static func sleepThrowing(_ seconds:Double) async throws {
        try await self.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
    }
}

The way to guarantee that a piece of work will be done on a background thread is to give that work to an Actor. That is what an Actor is for (in part).

So for example if an Actor has a method doSleep that calls Task.sleep, then if you instantiate that actor and call that method from your Task, it will sleep on a background thread.

like image 114
matt Avatar answered Oct 21 '25 21:10

matt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!