执行异步任务

时间:2019-02-07 09:00:59

标签: ios swift concurrency

我需要帮助以更好地了解Swift中的并发工作方式。

我有代码:

DispatchQueue.main.async {
    DispatchQueue.main.async {
        print("A")
        DispatchQueue.main.async {
            print("B")
        }
        print("C")
    }
    print("D")
}

结果: D A C B

我猜“ D”仅是第一个原因,执行第一个Dispatch块包括2个步骤:

  1. 将任务放入队列
  2. 执行任务

比执行 print(“ D”)需要更多的时间。是吗?

当我尝试并发队列时,在一种情况下,我得到了下一个结果: A D C B

为什么会这样?

并发队列代码:

DispatchQueue.global(qos: .utility).async {
    DispatchQueue.global(qos: .utility).async {
        print("A")
        DispatchQueue.global(qos: .utility).async {
            print("B")
        }
        print("C")
    }
    print("D")
}

1 个答案:

答案 0 :(得分:1)

此行为的原因是,可能有许多具有相同QoS的全局队列,但始终只有一个主队列。

您的第一个示例是可预测的-它的行为始终相同,因为您始终将任务分派到同一队列-main。用async提交的任务将异步执行(这意味着async函数将立即返回),但是新任务直到当前执行的任务完成后才开始执行。这是发生的事情的简化模型:

Task 1:
    Submit task 2
    Print "D"

Task 2:
    Print "A"
    Submit task 3
    Print "C"

Task 3:
    Print "B"

Task 1包括提交Task 2和打印内容。 Task 1正在主队列上运行,并且Task 2已添加到同一队列。这意味着Task 2在当前运行的任务-Task 1-完成执行之前无法启动。

Seconf示例有点不同。每次调用DispatchQueue.global时,都可以确保获得具有特定QoS的队列,但不一定是同一队列。您派遣print("A")的队列似乎没有任何其他待处理任务,并且能够在返回async方法之前立即执行其工作。

使用先前提供的模型-如果将Task 2添加到与正在运行的Task 1不同的队列中,则无需等待Task 1完成执行。但是同样,在这种情况下,这完全取决于每次调用DispatchQueue.global时获得的队列,并且不能保证