Can I limit concurrent requests using GCD?

I get data from the database asynchronously. Is there a way to limit concurrent queries to a number, but still execute the rest?

I saw a message using NSOperation and NSOperationQueue but this is too complicated for me. Are there any other ways to do this? Can a GCD achieve this?

+4
source share
3 answers

Something like that:

... //only make one of these obviously :) remaking it each time you dispatch_async wouldn't limit anything dispatch_semaphore_t concurrencyLimitingSemaphore = dispatch_semaphore_create(limit); ... //do this part once per task, for example in a loop dispatch_semaphore_wait(concurrencyLimitingSemaphore, DISPATCH_TIME_FOREVER); dispatch_async(someConcurrentQueue, ^{ /* work goes here */ dispatch_semaphore_signal(concurrencyLimitingSemaphore); } 
+15
source

I propose this solution for the limited simultaneous execution of synchronous tasks:

 func dispatch_async_batch(tasks: [() -> ()], limit: Int, completion: (() -> ())?) { if tasks.count > 0 || completion != nil { let q = dispatch_queue_create("dispatch_async_batch", DISPATCH_QUEUE_CONCURRENT); let sema = dispatch_semaphore_create(limit); dispatch_async(q, { for task in tasks { dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER) dispatch_async(q, { task() dispatch_semaphore_signal(sema) }) } if let completion = completion { dispatch_barrier_async(q, completion) } }) } } 

This approach has a small overhead: only one additional task is placed in the queue (i.e., one additional thread) in the direction currently being performed. This is especially good when you have a large total amount of tasks.

This gist is a ready-to-use demo, just put the code in the playground.

0
source

A simple way is to set n consecutive queues

 struct dataCalls { let n:Int func fetchIt(){ print ("Done",n) } init(n:Int){ self.n=n } } var dataCallsArray: [dataCalls]=[] var qArray:[dispatch_queue_t] = [] let n = 5 for i in 1...50 { dataCallsArray.append(dataCalls(n:i)) } for _ in 1...n { qArray.append(dispatch_queue_create(nil, nil)) } var i = 0 for data in dataCallsArray { dispatch_async(qArray[i%n], {() -> Void in data.fetchIt()}) i++ } 
-1
source

All Articles