[NSOperationQueue] Dépendances entre Groupes d'opérations concurrentes
ClicCool
Membre
Bonjour tous
Mon appli doit exécuter plusieurs séries d'opérations concurrentes.
Mais, si chaque opération d'un groupe doit être exécutée de façon concurrente, une fois un groupe exécuté le mainThread doit paramétrer la série d'opérations suivantes et en lancer l'exécution.
J'ai ainsi 3 groupes de 30 à plusieurs centaines d'opérations qui doivent se succéder.
Pour les groupes, actuellement j'utilise une [tt]NSOperationQueue[/tt] alimentée par des [tt]NSInvocationOperation[/tt].
Configurer des dépendances entre 2 opérations n'est pas adapté ici puisqu'il s'agit de groupes dont je ne connais à l'avance ni le nombre d'opération ni bien sur l'ordre dans lequel elles seront éxécutées.
Il y aurait bien le [tt]waitUntilAllOperationsAreFinished[/tt] des [tt]NSOperationQueue[/tt] mais ça bloquerait le mainThread !
Il y a-t-il un moyen d'être notifié de la fin d'exécution d'une [tt]NSOperationQueue[/tt] ?
De toutes façons il faut bien qu'on en soit informé pour pouvoir releaser la Queue non ?
Ma solution actuelle sur laquelle je souhaiterai votre avis
- Préparer, chaque fois, à l'avance un Array de toutes mes [tt]NSInvocationOperation[/tt] afin de les placer en une seule fois dans la [tt]NSOperationQueue[/tt]
- puis observer la propriété [tt]operationCount[/tt] de la [tt]NSOperationQueue[/tt] et envoyer l'Array suivant de [tt]NSInvocationOperation[/tt] dès que le compte est à zéro
- puis enfin, qand j'en ai plus besoin, releaser la [tt]NSOperationQueue[/tt]
Cette solution, pour fonctionnelle qu'elle semble être, me donne l'impression d'un bricolage pas propre.
Y'a-t-il plus propre et plus sûr comme méthode ?
Par exemple serait-il plus judicieux d'ajouter à mes arrays de [tt]NSInvocationOperation[/tt] une NSInvocationOperation spéciale, se contentant d'envoyer une Notification de "finDeQueue", avec bien sûr un bas niveau de priorité (NSOperationQueuePriorityVeryLow).
Ainsi, en principe, quand je reçois la Notification "finDeQueue", je peux en déduire que la NSOperationQueue a terminé son travail ... ?
Ca m'évite de tester plus de 100 fois le operationCount...
... ça me plait mieux en fait ...
... Mais ça me parait encore plus du bricolage ... :-\\
[EDIT] C'est même pas bon du tout comme soluce ça. Je recevrais alors la notification quand la dernière opération lancée (la spéciale) est terminée mais d'autres opérations lancées avant mais plus longues pourraient ne pas avoir fini ...
Des avis ?
MERCI
Mon appli doit exécuter plusieurs séries d'opérations concurrentes.
Mais, si chaque opération d'un groupe doit être exécutée de façon concurrente, une fois un groupe exécuté le mainThread doit paramétrer la série d'opérations suivantes et en lancer l'exécution.
J'ai ainsi 3 groupes de 30 à plusieurs centaines d'opérations qui doivent se succéder.
Pour les groupes, actuellement j'utilise une [tt]NSOperationQueue[/tt] alimentée par des [tt]NSInvocationOperation[/tt].
Configurer des dépendances entre 2 opérations n'est pas adapté ici puisqu'il s'agit de groupes dont je ne connais à l'avance ni le nombre d'opération ni bien sur l'ordre dans lequel elles seront éxécutées.
Il y aurait bien le [tt]waitUntilAllOperationsAreFinished[/tt] des [tt]NSOperationQueue[/tt] mais ça bloquerait le mainThread !
Il y a-t-il un moyen d'être notifié de la fin d'exécution d'une [tt]NSOperationQueue[/tt] ?
De toutes façons il faut bien qu'on en soit informé pour pouvoir releaser la Queue non ?
Ma solution actuelle sur laquelle je souhaiterai votre avis
- Préparer, chaque fois, à l'avance un Array de toutes mes [tt]NSInvocationOperation[/tt] afin de les placer en une seule fois dans la [tt]NSOperationQueue[/tt]
- puis observer la propriété [tt]operationCount[/tt] de la [tt]NSOperationQueue[/tt] et envoyer l'Array suivant de [tt]NSInvocationOperation[/tt] dès que le compte est à zéro
- puis enfin, qand j'en ai plus besoin, releaser la [tt]NSOperationQueue[/tt]
Cette solution, pour fonctionnelle qu'elle semble être, me donne l'impression d'un bricolage pas propre.
Y'a-t-il plus propre et plus sûr comme méthode ?
Par exemple serait-il plus judicieux d'ajouter à mes arrays de [tt]NSInvocationOperation[/tt] une NSInvocationOperation spéciale, se contentant d'envoyer une Notification de "finDeQueue", avec bien sûr un bas niveau de priorité (NSOperationQueuePriorityVeryLow).
Ainsi, en principe, quand je reçois la Notification "finDeQueue", je peux en déduire que la NSOperationQueue a terminé son travail ... ?
Ca m'évite de tester plus de 100 fois le operationCount...
... ça me plait mieux en fait ...
... Mais ça me parait encore plus du bricolage ... :-\\
[EDIT] C'est même pas bon du tout comme soluce ça. Je recevrais alors la notification quand la dernière opération lancée (la spéciale) est terminée mais d'autres opérations lancées avant mais plus longues pourraient ne pas avoir fini ...
Des avis ?
MERCI
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Ben oui, mais ça me dit seulement quand une des opérations de la queue est terminée, pas quand elles sont toutes terminées.
Je devrait donc observer des centaines isFinished pour décrémenter un compteur initialisé avec le nombre total d'opérations d'une série ...
C'est ça ton idée ?
A la base c'était la [tt]NSOperationQueue[/tt] que je voudrais surveiller, pas ses [tt]NSOperation[/tt].
N'y a-t-il pas un équivalent de isFinish pour une [tt]NSOperationQueue[/tt] ?
"operationCount" de NSOperationQueue est KVO-compliant
Suffit donc d'observer ça et de ne faire ce que tu veux que quand ça vaut zéro.
Tu trouves donc que "ma solution actuelle" est bonne ?
Sinon tu pourrais en effet faire une NSOperation qui ne fait rien et observer son isFinished, mais se baser sur le fait de lui mettre une priorité super basse n'est pas suffisant. Si tu voulais t'orienter par là , faudrait plutôt faire que cette opération spéciale soit dépendante de toutes les autres opérations, pour ne s'exécuter que quand toutes les autres sont finies.
Mais porquoi ne pas utiliser les "dependancies" des NSOperations justement comme tu l'évoquais, pour faire en sorte que tes opérations du groupe suivant ne s'exécutent que quand le groupe précédent est fini... Mais justement en utilisant une NSOperation qui ne fait rien et qui dépend des autres opérations de ton groupe d'opérations, pour synchroniser la finalisation de toutes les opérations de ce "groupe" ?
Alors, pour voir si je t'ai bien compris:
Il faudrait donc que je crée avant tout une [tt]NSOperation[/tt] bidon qui ne fait rien et, qu'à chaque création des mes multiples [tt]NSInvocationOperation[/tt], je l'ajoute à la liste des dependency de mon opération bidon avec un [tt]addDependency[/tt].
(Dommage qu'il n'existe pas une méthode addDependencies prenant un Array de NSOperations en argument )
A l'inverse, toutes les opérations du groupe suivant seraient, elles, dépendantes de la première opération bidon.
Et une deuxième opération bidon serait, elle, dépendante de toutes les opération du deuxième groupe.
Et ainsi de suite ...
J'ai bon là ? ???
Pour le addDependancies prenant un NSArray, il suffit d'écrire ça, c'est pas la mort :P
Merci
Je m'en vais donc utiliser cette stratégie :brule:
Vous parliez ici des NSOperationQueue et le titre de cet article est "[Grand Central Dispatch] ...".
En lisant le Concurrency Programming Guide d'apple j'avais pourtant l'impression qu'il s'agissait de deux choses différentes: GCD d'un côté et les Operation Queues de l'autre.
Qu'en est-il vraiment?
(Je ne connais pas encore vraiment GCD mais ai l'intention de m'y mettre dès que j'aurais un peu de temps)
Certes, si GCD est dispo pour la machine et qu'on est sous Snow Leopard, les NSOperationQueue utilisent automatiquement GCD en interne... Mais bon, là la question ne dépend pas de GCD, que ça l'utilise ou pas ça ne change pas l'issue de la question
[EDIT]
Quoique, pour être honnête, j'étais pas tout à fait sûr de ça quand j'ai posté le sujet :P
[EDIT2-PJ] Oh le saguoin ;D ;D ;D
3 secondes de retard t'as pas honte ?!
Y'a d'la relâche mon gars :P
Moi ça doit être l'effet "je fais mumuse avec mon nouvel iPhone 3GS" sans doute :P mais bon, j'y fonce (d'autant que le temps que je me dévore un chapitre de lecture, ça risque de pas être dodo avant 3h et faut être à l'heure au taf demain... ouch ;D).
J'ai pas tiré la chasse, je te laisse le faire si tu passes après moi. J'ai déjà éteint la lumière, du coup te vautre pas dans l'escalier.
T'as un nouvel iPhone 3Gs à TOI tout seul ? :kicking:
Et t'as même pas offert ta tournée ?
T'as de la chance qu'il soit trop tard sinon je me demande si j'aurais trouvé ça pas si bien ;D ;D