调度队列清晰解释

时间:2017-07-12 17:15:33

标签: swift3 grand-central-dispatch dispatch dispatch-async

我知道有很多关于调度队列,异步任务等的帖子,但是我无法从这些帖子中找到有用的解释,因为有太多的干扰因为额外的代码。我有人可以给我一个关于如何在任务A完成后启动任务B的明确指示吗?

我需要来自任务A的一些数据才能成功运行任务B,我知道我必须对DispatchQueue.async做一些事情,但我不知道究竟是怎么回事。

2 个答案:

答案 0 :(得分:2)

典型的过程是将async异步调度到某个串行队列。所以,假设您需要一些队列来处理图像,执行任务A然后执行任务B,然后在任务B完成时执行一些UI更新,您可以这样做:

let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".images")

queue.async {
    // do task A
}

queue.async { 
    // do task B
}

queue.async {
    // do whatever else is needed after B here

    DispatchQueue.main.async {
        // update model objects and UI here
    }
}

这是一种避免阻止主队列的模式,但是可以确保您连续执行A和B.

请注意,如果任务A或任务B本身是异步的,则上述操作无效。 (如果底层任务是异步的,也不会尝试使用sync。)在这些情况下,其他模式也适用。但是你的例子过于通用,而且我们有很多其他可能的模式可以枚举它们。如果你具体告诉我们A和B的任务是什么,我们可以提供更具建设性的建议。

另请注意,我明确建议不要同步调度(使用sync)。使用sync具有一定的直观吸引力,但它很少是正确的方法。阻塞调用线程(这是sync所做的)在很大程度上违背了首先拥有调度队列的目的。如果您尝试对某些共享资源进行线程安全访问,则应该使用sync的(很大程度上)唯一原因。但大多数情况下,您明确使用调度队列是为了从当前线程中获取一些耗时的任务。因此,将A和B async发送到串行队列,如果您想要执行其他操作,C,之后,您也将async发送到同一队列。

有关说明,请参阅Concurrency Programming Guide: Dispatch Queues。示例在Objective-C中,但所有概念都相同。您也可以访问WWDC videos并搜索“GCD”,您将获得许多精彩的视频,这些视频可以通过Grand Central Dispatch(更广泛的调度队列技术)。

答案 1 :(得分:1)

这样的事情怎么样?

import Dispatch

let queue = DispatchQueue(label: "My dispatch queue") //TODO: Give better label

let result1 = queue.sync { // "Task A"
    return "result 1"
}

let result2 = queue.sync { // "Task B", which uses result from Task A
    return result1.uppercased()
}

print(result2)