Ryan
Ryan

Reputation: 4884

DispatchGroup doesn't work as expected

I have made a DispatchGroup and run 2 async tasks. One is on main and the other one is on global().

As long as I understand, DispatchGroup.notify's block should invoked once all tasks are done but it doesn't work as I thought.

class Que {
    let group = DispatchGroup()

    init() {
        group.notify(queue: .main) {
        print("group done")
        }
    }

    func run() {
        doC()
        doD()
    }

    fileprivate func doC() {
        group.enter()
        DispatchQueue.main.async(group: group) {
            var rst = 0
            for idx in 0 ..< 500 {
                rst += idx
            }
            print("work item c is done")
            self.group.leave()
        }
    }

    fileprivate func doD() {
        group.enter()
        DispatchQueue.global().async(group: group) {
            var rst = 0
            for idx in 0 ..< 50 {
                rst += idx
            }
            print("work item d is done")
            self.group.leave()
        }
    }
}

The result is

work item d is done
group done
work item c is done

I want to know why it is not

work item d is done
work item c is done
group done

If I made C and D task run on global() queue, it worked.

Upvotes: 2

Views: 1037

Answers (1)

rmaddy
rmaddy

Reputation: 318794

You put the call to notify in the wrong place and called it far too early.

Most likely you want to call notify at the end of your run method.

init() {
}

func run() {
    doC()
    doD()

    group.notify(queue: .main) {
        print("group done")
    }
}

Note what is says in the documentation for the notify method:

Schedules a work item to be submitted to a queue when a group of previously submitted block objects have completed.

The bold is mine.

Upvotes: 4

Related Questions