4

I have n tasks sending to a server. When I launch them by [taskN resume] they will launch parallelly but i want to launch them sequentially - if first task finish, other task will launch. Any suggestions?

Patrik Vaberer
  • 646
  • 6
  • 15

2 Answers2

5

I came with quite simple solution without subclassing:

Sample:

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue setMaxConcurrentOperationCount:1];

    // first download task
    [queue addOperationWithBlock:^{
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); // create a semaphore


        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSessionTask *task1 = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {


            dispatch_semaphore_signal(semaphore); // go to another task
        }];
        [task1 resume];
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // wait to finish downloading

    }];
    // second download task
    [queue addOperationWithBlock:^{
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);


        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSessionTask *task2 = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {


            dispatch_semaphore_signal(semaphore);
        }];
        [task2 resume];
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    }];

These two operations (task1, task2) will execute sequentially, so they will wait until n-1 operation will finish.

Using semaphores inspired in NSURLSession with NSBlockOperation and queues

Community
  • 1
  • 1
Patrik Vaberer
  • 646
  • 6
  • 15
4

For this you are best using NSOperation and NSOperationQueue.

It manages a queue of tasks and each one is performed on a background thread.

By setting the queue to only have 1 concurrent operation it will queue them up like you want.

You should...

  1. Create an NSOperation subclass that does your downloading. Make it do SYNCHRONOUS downloads. They don't need to be asynchronous as they will already be on a background thread.

  2. Set up an NSOperationQueue and set maximumNumberOfConcurrentOperations to 1.

  3. Add your operations to the queue.

This is the easiest way to approach NSOperationQueue but there are many more things that you can do with it.

There are also several questions and tutorials about it so I won't go into full detail here as you should be able to find other SO questions.

Fogmeister
  • 76,236
  • 42
  • 207
  • 306