2 votes

Problèmes avec NSTask dans OS X 10.6 Snow Leopard

Est-ce que quelqu'un d'autre a vu ou entendu parler de problèmes avec NSTask dans 10.6?

Ce code fonctionnait bien hier, et ne fonctionne pas aujourd'hui.

NSTask *task = [converter task];
[task waitUntilExit];
NSLog(@"La tâche est terminée");

La tâche fait ce qu'elle est censée faire (j'ai vérifié la sortie et tout est bon), mais le programme restera indéfiniment en attente à la méthode waitUntilExit. J'ai quelques tests unitaires qui utilisent un code similaire, ils avaient tous passé précédemment, mais depuis hier, ils ne fonctionnent plus.

2voto

jrtc27 Points 6797

Vous devez ajouter la ligne magique suivante :

[task setStandardInput:[NSPipe pipe]];

1voto

bbum Points 124887

(1) Traitez-vous la sortie de la tâche de quelque manière que ce soit? Si c'est le cas, le tampon de sortie peut se bloquer si vous ne lisez pas et ne traitez pas les données en cours de route.

(2) Votre tâche attend-elle la fin de la ligne sur stdin avant de se terminer? Si c'est le cas, vous voudrez saisir stdin et le fermer explicitement.

Comme Peter l'a dit, vérifiez ps pour voir si votre tâche est toujours en cours d'exécution. Si c'est le cas, utilisez sample pour l'échantillonner et comprendre ce qu'il fait.

1voto

johne Points 5957

Peut-être - J'ai remarqué un problème avec une partie de mon code le 10.6 qui ressemble étrangement à votre problème.

J'avais besoin d'obtenir des informations réseau (surtout concernant BGP et AS) de manière totalement asynchrone. La solution idéale pour moi est d'envoyer des requêtes d'enregistrement DNS TXT spécial à un serveur DNS public, mais Cocoa/Core Foundation ne fournit pas d'API pour ce type de requêtes DNS étranges. Une autre solution était d'utiliser shell% whois -h IP 'SPECIAL REQUEST' et simplement analyser les informations pertinentes de la sortie. C'était quelque chose que je pouvais mettre en place en quelques heures et revenir plus tard pour mettre en place une vraie solution. Très bricolage, mais beaucoup plus rapide que 1) trouver une bibliothèque DNS asynchrone appropriée et 2) se familiariser avec son API et éventuellement écrire un wrapper pour elle.

Donc, j'ai créé une classe qui lance un thread en arrière-plan, puis utilise NSTask pour démarrer la requête whois. Le thread en arrière-plan reste dans une boucle NSRunLoop pour traiter les résultats, mais vérifie environ toutes les ~1/10 de seconde si le NSTask est mort pour une raison quelconque, ou si [NSThread isCanceled], etc. Il s'enregistre également pour les notifications NSApplicationWillTerminateNotification afin de pouvoir faire un nettoyage approprié si l'application se termine.

Eh bien, à partir de 10.6... je ne pouvais plus quitter 'rapidement'. Sur 10.5, tout est parfaitement fluide, et l'application se ferme instantanément, du moins perceptuellement. Sous 10.6, quitter provoque l' 'accrochage' de l'application. Le débogage a montré que tout était bloqué en essayant de nettoyer les whois NSTask persistants. Comme aucune des informations que j'obtiens de cette manière n'est critique pour la fonctionnalité de l'application (c'est un genre d'info supplémentaire, bon à savoir), j'ai juste arrêté d'essayer d'obtenir les infos en tant que solution provisoire.

Les rapides essais de débogage du problème ont montré que l'application principale bloquait en essayant d'acquérir les instances NSLock. Ce qui est intéressant, c'est que si je le laisse simplement, l'application finit par sortir normalement - de 10 à 20 secondes à quelques minutes.. il y a quelque chose qui a changé entre 10.5 et 10.6 qui fait que le code encadré dans un bloc [NSLock lock] ... [NSLock unlock] 'met du temps'. Je n'ai pas encore réussi à déterminer où cela se produit, cependant (ce n'est pas encore une priorité)... mais l'une de ces choses est de terminer le NSTask en arrière-plan s'il est encore en cours d'exécution et de 'attendre qu'il se termine' avant de pouvoir se débarrasser en toute sécurité de choses comme son NSPipe.

DUP: Cela pourrait être une réponse dupliquée... ma première semble avoir disparu dans l'au-delà?

1voto

gulli Points 11

0voto

Peter Hosey Points 66275

Vérifiez les ps, le haut, ou le Moniteur d'activité. Assurez-vous que votre processus est bien terminé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X