2017-08-14 10 views
1

DispatchGroupを作成し、2つの非同期タスクを実行しました。 1つはmainにあり、もう1つはglobal()にあります。DispatchGroupが期待どおりに動作しない

私が理解している限り、すべてのタスクが完了したらDispatchGroup.notifyのブロックが呼び出されるべきですが、思った通りに動作しません。

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

私はglobal()キューにCDタスクの実行を行った場合、結果はそれが

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

私が知りたい

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

ではありません、なぜ、それが働きました。

答えて

2

notifyへのコールを間違った場所に置き、あまりにも早く電話しました。

ほとんどの場合、runメソッドの最後にnotifyに電話します。

スケジュール以前提出ブロックオブジェクトのグループが完了したとき、作業項目がキューに提出する:何であるか

init() { 
} 

func run() { 
    doC() 
    doD() 

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

notifyメソッドのドキュメントで述べています。

太字は鉱山です。

+0

したがって、通常のコールバッククロージャのようには機能しません。私は一度それを設定すると、それは毎回グループでタクを呼び出されると思った。ありがとう! – Ryan

+1

キューに現在のタスクが存在しないときに呼び出されます(現在入力されているタスクに対して 'leave'が最後に呼び出された後)。 – rmaddy

関連する問題