Reputation: 8296
I'm trying to enforce a specific order for tasks to complete using Grand Central Dispatch but I'm having a bit of trouble understanding the correct way to do it. I tried using groups in the following way:
Initialization:
startup = dispatch_group_create();
Tasks that need to wait:
//Don't want to wait on the main thread, so dispatch async to a concurrent queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0L),^{
//Wait until we're finished starting up
dispatch_group_wait(startup,DISPATCH_TIME_FOREVER);
//Now we can do this stuff back on the main queue
dispatch_async(dispatch_get_main_queue(),^{
//Do work
});
});
Work that I need to wait for:
dispatch_group_async(startup,dispatch_get_main_queue(),^{ // work });
Due to the nature of my app, the tasks that need to wait can occur BEFORE the work that I need to wait for. What I really want is the ability to wait on a condition that way when the condition is done, it's done, and all future threads can do their thing. Does GCD have this?
Upvotes: 1
Views: 3620
Reputation: 4623
I'm not sure of all the details of your implementation, so forgive me if I'm repeating what you already know.
After you are done dispatching all of your tasks, use dispatch_group_notify. This will execute a block on the queue you specify once all the tasks assigned to the group have finished processing.
dispatch_group_notify(startup, dispatch_get_main_queue(), ^{
// Don't forget to release the dispatch group!
dispatch_release(startup)
// perform work block;
});
For a particular parsing activity, I need to do some processing of data that can be done while the rest of the parsing activity is ongoing. I assign the processing to a group on a concurrent queue. Then when my parsing is done, I check to see if the group is done. If it is done, I clean things up. If not, utilize the dispatch_group_notify() and execute the work afterwards. Something along these lines:
double delayInSeconds = 2.0;
dispatch_time_t groupWaitTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
if (dispatch_group_wait(myDispatchGroup, groupWaitTime)==0){
NSLog(@"dispatch group completed in time");
dispatch_release(myDispatchGroup);
[self parsingCompleteWithActivity:activity];
}else{
NSLog(@"dispatch group did not complete in time");
dispatch_group_notify(myDispatchGroup, dispatch_get_main_queue(), ^{
dispatch_release(myDispatchGroup);
[self parsingCompleteWithActivity:activity];
});
}
Good luck!
Upvotes: 2
Reputation: 8296
Works if I use a semaphore and then signal after each call to wait. Also works if I call dispatch_group_enter and dispatch_group_leave.
Upvotes: 0