0

Normally I can use DispatchGroup to track the tasks in multiple Dispatch task. But in order to make sure DispatchGroup works properly, the group.notify method has to be called after all of the group.enter are called for all the tasks.

The questions for now is, I am having a recursion, and in the recursion it creates more tasks, I want to make sure all of the tasks are completed. As I mentioned earlier, the DispatchGroup.notify won't work properly if it's called earlier than all the group.enter. In this recursion case you won't know when the which is the last group.enter call.

Simplist Example:

func findPath(node: Node) {
  if !node.isValid { return }
  queue.async { //concurrent queue
    findPath(node.north)
  }
  queue.async {
    findPath(node.west)
  }
  queue.async {
    findPath(node.south)
  }
  queue.async {
    findPath(node.east)
  }
}

This is the simplest example, in my case there are a lot more async blocks, like image fetching, network api call, etc. How would I make sure that the findPath function in this example would completely finished by all the tasks from the Dispatch queue?

Tony Lin
  • 922
  • 6
  • 25

1 Answers1

2

The closure associated with the dispatchGroup.notify isn't called until the last dispatchGroup.leave is called, so you call enter outside the asynchronous task and leave inside

Something like:

func findPath(node: Node) {
  if !node.isValid { return }
  dispatchGroup.enter()
  queue.async { //concurrent queue
    findPath(node.north)
    dispatchGroup.leave()
  }

  dispatchGroup.enter()
  queue.async {
    findPath(node.west)
    dispatchGroup.leave()
  }

  dispatchGroup.enter()
  queue.async {
    findPath(node.south)
    dispatchGroup.leave()
  }

  dispatchGroup.enter()
  queue.async {
    findPath(node.east)
    dispatchGroup.leave()
  }
}


func findPaths(startNode: Node) {
    findPath(node: startNode)
    dispatchGroup.notify {
        print("All done")
    }
}
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • 1
    To pile on, if you need to spawn more tasks inside those queues, you can pass the DispatchGroup as a parameter. The DispatchGroup is a thread safe class that you can update from anywhere. – binaryPilot84 Sep 07 '18 at 12:02