1

I am trying to add a background threaded operation to a NSOperation queue and want to make it execute in a sequence, so I set setMaxConcurrentOperationCount to 1 but not able to achieve synchronous process.

I tried with below code,

 NSOperationQueue *queue = [NSOperationQueue new];
[queue setMaxConcurrentOperationCount:1];


    [queue addOperationWithBlock:^{

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
            for (uint i=0; i<=9999999; i++) {
                NSLog(@"Loop A");
            }
        });
    }];

[queue addOperationWithBlock:^{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    for (uint i=0; i<=9999999; i++) {
        NSLog(@"Loop B");
    }
    });
}];

That Will Log like,

2016-01-04 17:25:41.861 TestOperation[582:111196] Loop B
2016-01-04 17:25:41.861 TestOperation[582:111194] Loop A
2016-01-04 17:25:41.864 TestOperation[582:111196] Loop B
2016-01-04 17:25:41.866 TestOperation[582:111194] Loop A
2016-01-04 17:25:41.867 TestOperation[582:111196] Loop B
2016-01-04 17:25:41.867 TestOperation[582:111194] Loop A
2016-01-04 17:25:41.868 TestOperation[582:111194] Loop A
2016-01-04 17:25:41.869 TestOperation[582:111194] Loop A

and want this operation to complete Loop A first and then Loop B.

Parth Pandya
  • 1,460
  • 3
  • 18
  • 34
Anand Suthar
  • 3,678
  • 2
  • 30
  • 52

3 Answers3

2

You just shouldn't be using dispatch_async. You are already moving the work to a background thread by using an operation queue so you don't need to move again using dispatch_async. By using dispatch_async you are allowing the operations to finish and then you have 2 other background threads processing concurrently.

Wain
  • 118,658
  • 15
  • 128
  • 151
1

You seem to be totally confused about NSOperationBlock and dispatch_async. The NSOperationBlock operations both dispatch to a background queue. The dispatch takes close to zero time, then the NSOperationBlock is finished, and the next NSOperationBlock runs. Which dispatches another block. Then both block run on different threads, each logging stuff. Your output is exactly what is expected.

If you want one thing to happen after the other, the easiest way is that one block calls the other just before it is finished.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
0

I was also facing similar problem a while ago, but your seems different but you can use this class developed by me

https://www.cocoacontrols.com/controls/sktaskmanager

you can create small tasks and execute that task in sequentially or concurrently.

SKTask *aTask1=[SKTask taskWithBlock:^(id result, BlockTaskCompletion completion) {
        // your async task goes here i.e. image downloading in background

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        for (uint i=0; i<=9999999; i++) {
            NSLog(@"Loop A");
        }
        // once task is completed call this block
        completion(nil); //this is important otherwise next task will not be exexute 
 });
}];


SKTask *aTask2=[SKTask taskWithBlock:^(id result, BlockTaskCompletion completion) {
    // your async task goes here i.e. image downloading in background
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        for (uint i=0; i<=9999999; i++) {
            NSLog(@"Loop B");
        }
        // once task is completed call this block
        completion(nil); //this is important otherwise next task will not be exexute 

    });
}];

Create As many as task you want and add that all tasks to one array call this method with array that contains all SKTask object

[SKTaskManager sequenceOperations:arrTask completion:^{
    NSLog(@"all task completed");
}];

This will execute task sequentially so once aTask1 is completed then and then aTask2 will starts.

Happy Coding

Sunil_Vaishnav
  • 425
  • 1
  • 5
  • 15