繁体   English   中英

Swift - async/await - 在 MainActor 任务的后台线程上执行异步方法

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

这是我的viewDidLoad方法:

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

        await doSomeBackgroundWork()

        doSomeWorkOnMainThread3()
        doSomeWorkOnMainThread4()
    }
}

这是我应该在后台线程上执行工作的方法:

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

是否可以在后台线程上执行doSomeBackgroundWork (不使用 GCD),并在返回主线程之前等待它?

您正在寻找 Task.sleep。 请注意,它以纳秒为单位,这真的很奇怪,所以我写了一个扩展来切换到秒; 要获得它,您必须使用 Double,而不是 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))
    }
}

保证在后台线程上完成一项工作的方法是将这项工作交给一个 Actor。 这就是 Actor 的用途(部分)。

例如,如果一个 Actor 有一个调用Task.sleep的方法doSleep ,那么如果您实例化该 Actor 并从您的 Task 调用该方法,它将在后台线程上休眠。

该解决方案有效,但我猜它并不完美:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM