Comment arrêter/annuler/suspendre / reprendre des tâches sur la file D'attente GCD

Comment arrêter/annuler/suspendre / reprendre les tâches sur la file D'attente GCD

comment arrête-t-on les opérations de la file d'attente en arrière-plan? Je veux arrêter quelques écrans dans notre application. Et certains écrans, il convient de reprise automatique. Alors, comment passe-t-on une file d'attente dans iOS?

je veux dire quand l'Utilisateur a parcouru l'application au moment où nous lançons le thread de fond dans dispatch_queue_t. Mais il ne s'arrête jamais et reprend dans le code. Alors, comment fait-on suspendre et reprendre une file d'attente

21
demandé sur lakshmanbob 2015-04-07 16:22:31

2 réponses

Pour suspendre un message de la file d'attente, c'est tout simplement dispatch_suspend(queue) dans L'Objectif-C ou Swift 2.3, ou queue.suspend() dans Swift 3. Cela n'affecte pas les tâches en cours d'exécution, mais empêche simplement les nouvelles tâches de commencer sur cette file d'attente. De plus, vous ne suspendez évidemment que les files d'attente que vous avez créées (pas de file d'attente globale, pas de file d'attente principale).

Pour reprendre un message de la file d'attente, c'est dispatch_resume(queue) dans L'Objectif - C ou Swift 2.3, ou queue.resume() dans Swift 3. Il n'y a pas de notion de "reprise automatique", donc vous avez juste à manuellement reprendre au moment opportun.

pour passer une file d'attente d'expédition autour, vous passez simplement le dispatch_queue_t objet que vous avez créé lorsque vous avez appelé dispatch_queue_create() dans L'Objectif C ou Swift 2.3, ou, dans Swift 3, le DispatchQueue objets que vous créez avec DispatchQueue(label:).

en termes d'annulation des tâches en attente sur les files d'attente de répartition, c'est une nouvelle fonctionnalité de iOS 8 et vous appelleriez dispatch_block_cancel(block) de votre dispatch_block_t objet en Objective-C ou Swift 2.3, ou item.cancel() d'un DispatchWorkItem dans Swift 3. Cela annule les blocs/items mis en file d'attente qui n'ont pas commencé, mais n'arrête pas ceux qui sont en cours. Si vous voulez être en mesure d'interrompre un bloc/article expédié, vous devez examiner périodiquement dispatch_block_testcancel() dans L'Objectif C et Swift 2.3, ou item.isCancelled dans Swift 3.

l'annulation des blocks GCD est suffisamment compliquée pour que je puisse vous renvoyer à la vidéo WWDC 2014 la Puissance, des Performances et de Diagnostic: Quoi de neuf dans PGCD et XPC, qui vous présente le concept d'expédition des objets bloqués, faisant la queue, les annulant, etc. Bien que cela décrive L'ancienne API Objective-C et Swift 2.3, tous les concepts sont également applicables à la nouvelle API Swift 3.

si vous voulez annuler des tâches, vous pouvez également envisager d'utiliser les files d'attente d'opération,NSOperationQueue dans L'Objectif-C ou Swift 2.3, A. K. A. OperationQueue dans Swift 3, comme ses opérations annulables ont été autour pendant un certain temps et vous êtes probablement trouver beaucoup d'exemples en ligne. Il appuie également la restriction du degré de concurrence avec maxConcurrentOperationCount (alors qu'avec les files d'attente d'expédition vous ne pouvez choisir entre série et concurrent, et contrôler la concurrence plus que cela nécessite un petit effort de votre part).

si vous utilisez operation queues, vous suspendez et reprenez en changeant le suspended propriété de la file d'attente. Et à la transmettre autour de vous, vous venez de passer l' NSOperationQueue objet que vous instancier.


ayant dit tout cela, je vous suggérerais d'élargir votre question pour préciser quelles sortes de tâches sont en cours à l'arrière-plan et expliquer pourquoi vous voulez les suspendre. Il pourrait y avoir de meilleures approches que de suspendre la file d'attente en arrière-plan.


dans vos commentaires, vous mentionnez que vous utilisiez NSTimer, A. K. A. Timer dans Swift 3. Si vous souhaitez arrêter une minuterie, appeler timer.invalidate() pour l'arrêter. Créer un nouveau NSTimer quand vous voulez recommencer.

ou si la minuterie tourne vraiment sur un thread d'arrière-plan, les minuteries GCD le font beaucoup plus gracieusement, en évitant la sottise de devoir créer un runloop sur un thread d'arrière-plan, que vous devez exécuter NSTimer sur les fils de fond. Avec une minuterie GCD, vous pouvez la suspendre/reprendre tout comme vous suspendez/reprendre une file d'attente, en utilisant simplement l'objet timer au lieu de l'objet File d'attente.

47
répondu Rob 2017-01-27 09:48:29

Vous ne pouvez pas mettre en pause / annuler en utilisant une file D'attente GCD. Si vous avez besoin de cette fonctionnalité (et dans de nombreux cas, même si ce n'est pas le cas), vous devriez utiliser L'API de niveau supérieur - NSOperationQueue. Ceci est construit sur GCD mais vous donne la possibilité de contrôler combien de choses sont exécutées en même temps, de suspendre le traitement de la file d'attente et d'annuler les opérations individuelles / toutes.

3
répondu Wain 2015-04-07 13:28:51