[NSOperationQueue] Dépendances entre Groupes d'opérations concurrentes

ClicCoolClicCool Membre
décembre 2009 modifié dans API AppKit #1
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

Réponses

  • AliGatorAliGator Membre, Modérateur
    20:59 modifié #2
    "isFinished" de NSOperation est KVO-compliant ;)
  • ClicCoolClicCool Membre
    20:59 modifié #3
    dans 1260628533:

    "isFinished" de NSOperation est KVO-compliant ;)


    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 ...
  • ClicCoolClicCool Membre
    20:59 modifié #4
    A moins d'observer le isFinished d'une [tt]NSOperation[/tt] spéciale, ne faisant finalement rien mais avec un bas niveau de priorité (NSOperationQueuePriorityVeryLow) garantissant qu'elle soit bien exécutée en dernier... c'est plus beau en effet que ma dernière idée citée plus haut avec sa Notification ... sauf que exécutée en dernier ne signifie pas terminée en dernier ...  B)

    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] ?
  • AliGatorAliGator Membre, Modérateur
    décembre 2009 modifié #5
    Ah oui ok pardon. Bon, bah je la refais alors :

    "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.
  • ClicCoolClicCool Membre
    20:59 modifié #6
    dans 1260629714:

    Ah oui ok pardon. Bon, bah je la refais alors :

    "operationCount" de NSOperationQueue est KVO-compliant ;)


    Tu trouves donc que "ma solution actuelle" est bonne ?
  • AliGatorAliGator Membre, Modérateur
    20:59 modifié #7
    Bah oui, je vois pas pourquoi ça serait du bricolage ;)

    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" ?
  • ClicCoolClicCool Membre
    20:59 modifié #8
    Ca me plait mieux ce que tu suggères.

    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à  ?  ???
  • AliGatorAliGator Membre, Modérateur
    20:59 modifié #9
    Yep, tout bon ;)

    Pour le addDependancies prenant un NSArray, il suffit d'écrire ça, c'est pas la mort :P
    for(NSOperation* op in operationsArray)<br />&nbsp; [groupDummyOperation addDependancy:op]
    
  • ClicCoolClicCool Membre
    20:59 modifié #10
    dans 1260631856:

    Yep, tout bon ;)

    Pour le addDependancies prenant un NSArray, il suffit d'écrire ça, c'est pas la mort :P
    for(NSOperation* op in operationsArray)<br />&nbsp; [groupDummyOperation addDependancy:op]
    



    Merci 

    Je m'en vais donc utiliser cette stratégie  :brule:
  • iSofTomiSofTom Membre
    20:59 modifié #11
    J'ai une petite question qui n'est pas complètement en rapport avec la question initiale...

    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)
  • MalaMala Membre, Modérateur
    20:59 modifié #12
    Les NSOperationQueues bénéficient automatiquement de GCD si on fait tourner l'appli sous Snow Leopard. C'est dans l'ordre des choses en même temps car il y a une certaine continuité entre les deux.
  • AliGatorAliGator Membre, Modérateur
    20:59 modifié #13
    Oui j'avoue que je n'ai pas compris pourquoi ClicCool avait mis GCD dans le titre.
    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 ;)
  • ClicCoolClicCool Membre
    décembre 2009 modifié #14
    Oui en effet,je vais de ce pas modifier le titre du Thread ;)

    [EDIT]
    dans 1260831780:
    .../...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 ;)

    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 ?!
  • AliGatorAliGator Membre, Modérateur
    20:59 modifié #15
    Oups :P J'avais même pas fait gaffe à  l'heure... (j'ai même 3 minutes de retard, et non pas juste trois secondes ::))
  • ClicCoolClicCool Membre
    20:59 modifié #16
    Ah oui tiens, 3 minutes.
    Y'a d'la relâche mon gars :P
  • AliGatorAliGator Membre, Modérateur
    20:59 modifié #17
    En attendant je vois que t'es pô bien couché toi non plus malgré l'heure...
    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.
  • ClicCoolClicCool Membre
    20:59 modifié #18
    QUOI ?

    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
Connectez-vous ou Inscrivez-vous pour répondre.