2010-11-21 35 views
0

Prenez votre gadget Google Desktop moyen. Ajoutez le code suivant:Comment autoriser un gadget de bureau Google à mettre à jour son interface utilisateur (gérer les entrées utilisateur) alors que le code sous-jacent est occupé/bloqué?

debug.trace("go!"); 
for (var i = 0; i < 100000000; i++) { // google desktop stops responding 
     j = 12 * i; 
} 
debug.trace("finished"); 

Tous les gadgets de bureau Google verrouillent/gel pendant toute la durée, y compris le gadget le code est en cours d'exécution dans (le raccourci double quart de travail normal ne fonctionne pas, vous pouvez ne déplacez aucun gadget ou n'interagissez pas avec eux d'une autre manière: l'icône de la barre des tâches est réactive, mais ne fait rien - par exemple, la page des options n'est pas chargée tant que le code n'est pas terminé).

Je cherche un moyen de contourner cette situation générale (mon cas est que je fais des appels de fonction externes via une DLL qui prend beaucoup de temps à retourner, voir gmanifest 'install' élément). Le fait que les appels (/ code ci-dessus) soient déclenchés via setInterval/setTimeout ne semble pas faire de différence, et aucun code qui serait normalement appelé par un timer ne sera exécuté pendant que l'appel long est en cours.

Je suppose que cela est possible, parce que lorsque vous essayez le code suivant à la place de la boucle occupée ou mon blocage d'appel de fonction externe, rien ne se bloque:

var wsh = new ActiveXObject("WScript.Shell"); 
wsh.run("cmd.exe",1,true); // true = block until program has exited 
// UI responds in this period 
debug.trace("finished"); // occurs when cmd.exe is closed 

Je ne Je ne sais pas quelle est la différence entre ces trois cas. Des idées, et plus important encore, un moyen de contourner cela?

Pensées:

  • La boucle est occupée ne bloque pas en tant que telle, mais simplement d'utiliser tous temps processeur si rien ne se passe est donc pas représentatif (semble peu probable) [edit: non, il bloque ]

  • La DLL ou question que je l'utilise est défectueux ou mal, respectivement (pourrait être, je peux ajouter plus de détails si nécessaire) [edit: ne semble pas, juste un appel de blocage normale]

  • google gadgets "connaît" wscript.shell et carrie s en cours alors que "run" bloque (semble peu probable) [edit: sans réponse!]

  • Je pourrais générer un thread de travail pour le code de blocage (je ne trouve rien sur le contrôle de thread explicite dans les gadgets) [ éditer: pas possible; javascript a un seul thread]

  • Enveloppez l'appel de bloc dans un programme externe, fichier d'interrogation pour les mises à jour d'état (voir réponse)

Répondre

0

Javascript exactement un thread exécutant avec une pile d'appel. Vous ne pouvez pas parquer ce thread, en sauvant la pile d'appels et le reprendre plus tard.

La méthode javascript pour que les choses restent réactives est de s'assurer que vous recevez un rappel lorsque l'exécution est prête. En règle générale, ne monopolisez jamais le fil et attendez que quelque chose se produise.

C'est pourquoi il y a un A dans AJAX (asynchrone) - même si vous pouvez rendre XmlHttpRequest synchrone, c'est généralement considéré comme une mauvaise idée.

+0

Merci; Que faire si la DLL que j'utilise n'a pas de callback, et que je n'ai aucun contrôle sur la DLL? Dois-je envisager d'encapsuler les appels DLL dans un programme distinct? Comment cette explication s'intègre-t-elle à l'exemple d'exécution de wscript que j'ai posté ci-dessus? Il n'y a pas de rappel en cours, il semble être synchrone, et pourtant l'interface utilisateur du gadget et d'autres widgets continuent à fonctionner. – Michael

+0

Je ne suis pas un expert en DLL ou WScript.Shell, mais je voudrais envelopper la commande dans un script shell, peut-être en utilisant un fichier pour enregistrer le résultat. Quelque chose comme: 'launch.bat' - lance la commande de blocage et redirige la sortie vers un fichier. 'poll.bat' - vérifie la sortie du fichier et le retourne si disponible. Ensuite, je ferais un 'setTimeout()' en javascript et lancerait 'poll.bat' toutes les 500ms environ, indiquant la progression à l'utilisateur. Une attente occupée. –

+0

Merci, sans autres idées je vais aller avec celui-ci (même si poll.bat peut tout aussi bien être javascript dans le programme principal). J'aimerais savoir ce qui rend l'exécution de wscript.shell différente de tout autre appel bloquant si ... – Michael