skip to Main Content

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 ?

2

Answers


  1. Chosen as BEST ANSWER

    This solution is working, but it's not perfect I guess :

    func doSomeBackgroundWork() async {
        await Task {
            // long image processing task
            assert(!Thread.isMainThread)
        }.result
    }
    

  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search