2017-02-22 3 views
0

J'ai deux appels API comme suit:dispatch_async comprendre l'ordre d'exécution

-(void) doTask1{ 

    dispatch_async(queueSerial, ^{ //B1 

    [fileObj setFileInfo:file]; 

    }); 
} 

-(void) doTask2{ 

    dispatch_async(queueSerial, ^{ //B2 

     [fileObj getFileInfo:fileName completion:^(NSError *error) { 
      dispatch_async(queueSerial2, ^{ 
       //completion work C1 
      }); 
     }] 

    }); 
} 

Maintenant, ma question est, de ce que je comprends déjà en lisant GCD, si un processus appelle doTask1 et immédiatement après les appels doTask2, il se traduira par les deux en file d'attente et B1 en avance B2.

Cependant, est de s'assurer que B1 est entièrement exécuté avant que B2 commence à s'exécuter? Parce que le fichier mis à jour par B1 est utilisé par B2. Si B2 commence à s'exécuter avant que B1 soit complètement terminé, cela peut entraîner des problèmes.

Ou est-il préférable de faire

-(void) doTask1{ 
    dispatch_sync(queueSerial, ^{B1}); 
} 

-(void) doTask2{ 
    dispatch_sync(queueSerial, ^{B2}); 
} 

Répondre

1

Si queueSerial est vraiment une file d'attente de série, puis B1 se termine avant B2 commence. Il n'y a aucune garantie concernant la relation entre ceux-ci et tout ce qui a appelé les méthodes doTaskN ... qui seraient affectées par la modification _sync.

Si B1 ou B2 effectuent eux-mêmes le dispatching, cela n'est pas non plus contrôlé par la sérialisation.

+0

Merci pour votre commentaire. J'ai modifié ma question pour ajouter plus de détails sur le code. La chose que je ne comprends pas est votre commentaire sur "Il n'y a aucune garantie concernant la relation entre ceux-ci" Qu'est-ce que cela signifie? – ExceptionHandler

+0

Je veux dire que, dans le cas asynchrone, quel que soit le code appelle doTask1(), doTask2() peut avoir fait diverses autres opérations avant que le travail envoyé soit terminé. Dans le cas de la synchronisation, l'appelant s'arrête également jusqu'à la fin de vos opérations de file d'attente série. –

+0

Je vois. Je comprends cette partie. Si B2 envoie son gestionnaire d'achèvement à une autre file d'attente, est-il possible que ce bloc d'achèvement soit exécuté avant la fin de B1? Y at-il un moyen de s'assurer que cela n'arrivera pas et que le bloc d'achèvement dans B2 attend jusqu'à ce que B1 soit fini? – ExceptionHandler

0

Si vous utilisez une file d'attente série, votre tâche sera terminée dans le même ordre (premier entré, premier sorti), mais si vous utilisez concurrente, vous n'aurez aucune garantie quant à la fin de la commande.

-(void) doTask1{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    //your code 
    }); 
} 

-(void) doTask2{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    //your code 
    }); 
} 

Voici une grande explication de GCD et NSOperation pour concurrency: https://www.appcoda.com/ios-concurrency/

Vous devez être sûr que les deux tâches sont envoyées à la même file d'attente.

Mise à jour: Une autre approche consiste à utiliser NSOperation car vous pouvez définir une dépendance entre les tâches pour vous assurer que l'une est terminée avant de démarrer l'autre.

0

Si la tâche B1, qui a été envoyée à la file d'attente série, n'initie rien d'asynchrone, vous êtes assuré que B1 se terminera avant le démarrage de B2. Mais si B1 fait quoi que ce soit d'asynchrone (par exemple, une requête réseau, etc.), alors vous avez besoin d'autres patterns pour vous assurer que B2 ne démarre pas avant la fin de la tâche asynchrone de B1 (ex: dispatch_group_notify tâches dans les sous-classes asynchrones personnalisées NSOperation, etc.).

+0

J'ai modifié la question un peu plus et j'ai créé une nouvelle question [ici] (http://stackoverflow.com/questions/42403595/forcing-the-order-of-execution-using-dispatch-sync). Seriez-vous capable de m'aider à comprendre celui-ci? Je ne suis pas sûr de savoir comment utiliser l'appel 'dispatch_group_notify' ici car ce sont 2 méthodes différentes – ExceptionHandler