Tony Lin
Tony Lin

Reputation: 942

how to monitor when tasks of dispatch queue in recursion all completed?

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?

Upvotes: 0

Views: 729

Answers (1)

Paulw11
Paulw11

Reputation: 115051

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")
    }
}

Upvotes: 2

Related Questions