如何仅在一个线程上运行任务?

时间:2019-07-10 09:29:18

标签: swift concurrency grand-central-dispatch dispatch-queue

说我有几个数据库写闭包,我想在一个线程上执行它们,而不是成批执行-我需要在每次写写后更新UI。

串行队列,如:

DispatchQueue.global(qos: .background).async {}

DispatchQueue(label: "hello world").async {}

虽然可以连续运行,但可以在他们希望运行的任何线程中运行。

如何让一个只能在一个后台线程上运行的队列?

1 个答案:

答案 0 :(得分:2)

正如其他人指出的那样,代码在哪个线程上运行并不重要。诸如此类的性能问题通常取决于简单地一次依次运行任务,因此它们不会与资源重叠或冲突。

最简单的解决方案是创建一个顺序队列。 (在Safari中输入,因此值得您为此花每一分钱)

let queue = DispatchQueue(label: "db.update", qos: .utility, attributes: [], autoreleaseFrequency: .inherit, target: nil)

var progress: Int = 0

queue.sync {
    // Dome some work, then update the UI
    progress = 2
    DispatchQueue.main.async(execute: {
        // label.text = "did something"
        // progress.doubleValue = Double(progressCounter)
    })
}

queue.sync {
    // Do some more work
    progress += 1
    // This won't execute until the first block has finished
}

queue.sync {
    // Even more work
    progress += 1
}

queue.sync {
    // And so on...
    progress += 1   // This block might, for example, notify the system that everything has finished
    print("progress is finally \(progress)")
}

关键是每个块都按顺序执行(因为队列不是“并发的”),并且下一个块要等到前一个块完成后才能开始。每个块可能在也可能不在同一线程上执行,但这无关紧要。

一个块的结果/进度可以很容易地通过闭包变量传递给下一个块。