dugla
dugla

Reputation: 12954

Grand Central Dispatch. How Do I Query a Queue to see if it is in use?

What is the best/simplest way to detect if a queue I have created is currently in use? My intent here is to defer a particular action until all queued tasks have completed.

Thanks,
Doug

UPDATE

Here is a bit more context. I have an async serial queue (private dispatch queue) that is a property of my object. When this queue completes its work it calls dispatch_async(dispatch_get_main_queue(), {...}) to up date the UI. Currently the app runs only in landscape interface orientation. I am now adding support for both portrait & landscape interface orientation. For now, I prefer not to allow the interface to rotate to/from portrait/landscape while my GCD async task is running. So in my controller's shouldAutorotateToInterfaceOrientation: method I want to return NO during those periods.

Upvotes: 2

Views: 306

Answers (2)

Kurt Revis
Kurt Revis

Reputation: 27994

There's no direct support for that in GCD. You can probably get the effect you're looking for in other ways, though.

  • Do you just want to run a block after other blocks have completed? Put the blocks in a dispatch_group, and submit your "after everything's done action" using dispatch_group_notify. This works with concurrent or sequential queues.

  • Similarly, put your blocks in a group, and call dispatch_group_wait(group, DISPATCH_TIME_NOW). If it returns non-zero, then there are outstanding blocks in the group.

  • Is your queue sequential, and you want to wait until the other blocks have completed, blocking the current thread until then? Just issue your handler using dispatch_sync on the same queue.

There are other possibilities, depending on your exact situation.

Edit: Based on your update, there's an even easier way:

  • add a BOOL property to your view controller, called allowsOrientationChange
  • override -shouldAutorotateToInterfaceOrientation: to return self.allowsOrientationChange
  • at the start of your work block, do a dispatch_async to set the property to NO
  • at the end of your work block, do a dispatch_async to set the property to YES

(There's a little bit of a race condition between when the property is set to NO on the main thread, and when the rest of your work happens in the queue. You could make it a dispatch_sync if that really matters. Depends on what your reasons are for preventing rotation, I suppose.)

Upvotes: 2

warrenm
warrenm

Reputation: 31782

If you're in control of all the tasks going into the queue whose completion you care about, you can use the dispatch group APIs to group them together and get notified when they complete. If you aren't using a queue whose tasks you're completely in control of, you can roll your own notification by queueing a block whose sole purpose is to generate such a notification (though this really only applies if you're using a serial queue).

Upvotes: 1

Related Questions