On Aug 31, 2012, at 1:08 AM, Andreas Grosam wrote:

> I have a number of operations that will be received serially. Each operation 
> can be processed concurrently with respect to each other. I would like to 
> invoke the completion blocks for each operation in the order as they have 
> been received.



If you have operations A, B, C, D where which should execute concurrently, but 
their results used serially then:


dispatch_queue_t serialQueue = …;
dispatch_queue_t concurrentQueue = (global queue, or a new concurrent queue);




dispatch_semaphore_t semaphoreA = dispatch_semaphore_create(0);
__block id resultsOfA = nil;


wrapA = ^{
        resultsOfA = runA();
        dispatch_semaphore_signal(semaphoreA);
}


doneA =^{
        dispatch_semaphore_wait(semaphoreA);
        completionHandlerForA(resultsOfA);
}




// the completion handlers are pushed onto a serial queue
// but will not execute until the semaphore is signaled
// after the work is done
dipatch_async(doneA, searialQueue);
dipatch_async(doneB, searialQueue);
dipatch_async(doneC, searialQueue);
dipatch_async(doneD, searialQueue);

// The work fires off concurrently
dispatch_async(wrapA, concurrentQueue);
dispatch_async(wrapB, concurrentQueue);
dispatch_async(wrapC, concurrentQueue);
dispatch_async(wrapD, concurrentQueue);




> I'm searching a simple approach to achieve this, implemented using 
> NSOperationQueue, NSOperation and dispatch lib.


You can do the above with NSOperationQueue using a serial queue and concurrent 
queue, but you must use dependencies between the operations to enforce the 
serial execution of the completion handlers. The standard behavior of a serial 
NSOpQ is that only one thing may be executed at a time, but it *does not care 
which order they were submitted in*. It's first *ready* first out, not first in 
first out. So although you may have a dependency that the completion handler 
operation come after the work operation, if B finishes before A, B's completion 
handler will run first. To stop that you need to have a dependency that A 
complete before B. The trouble with this is that it ends up with a chain of 
retains through the dependencies properties (dependencies aren't dropped from 
the operation even if they're met), so you need to manually remove it from 
within the operation itself. It's messy.




--
Seth Willits




_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to