Forums : Xul, Xbl, JS...

Aller à la discussion :  Plus récente Plus ancienne

Aller à la page :  1 2

# Thread javascript

Envoyé par : papy

Date : 08/08/2006 11:52

(Re) bonjour,

je commence doucement à utiliser des threads pour mon interface, mais je n'ai trouvé qu'une méthode sleep et pas de méthode wait et resume. Ca me semble plutôt étonnant vu que ce sont des fonctionnalités assez utilisées dans le contexte des threads. Est ce que c'est moi qui ai louché ou est ce que vraiment on ne peut pas le faire ?

# Re: Thread javascript

Envoyé par : laurentj

Date : 14/08/2006 10:19

Ce ne serait pas les méthodes interrupt et join que tu cherches ?

# Re: Thread javascript

Envoyé par : papy

Date : 14/08/2006 22:01

Peut être bien, c'est vrai que je n'ai pas tester. J'ai l'habitude de travailler avec des threads mais en C, Java etc... et les noms de ces méthodes sont plutôt utilisés respectivement pour killer le thread et attendre que le thread termine dans ce contexte.

Ce que je cherche c'est de mettre un thread en pause, et le réveiller, comme ferait un mutex en fait, mais sans killer ou attendre la fin du thread.

Je vais quand même tester ces deux fonctions au cas ou, mais si c'est bien ca le choix des noms n'est pas vraiment aproprié vu que ca porte beaucoup à confusion avec l'utilisation standard qui en est faite.

En tout cas merci de m'avoir répondu, ca fait quand même avancé le smilblik ;)

# Re: Thread javascript

Envoyé par : Paul Rouget

Date : 15/08/2006 08:13

En effet, l'API scriptable du composant des threads est assez pauvre, cela vient du fait que l'on peut difficilement envisager une gestion des threads poussée à travers XPConnect. Si tu veux aller plus loin, il faut que tu regardes du coté de NSPR, mais ce n'est pas du JS.

# Re: Thread javascript

Envoyé par : papy

Date : 15/08/2006 12:49

Merci pour cette réponse, au moins je suis fixé sur ce point. Il me reste juste une petite question :

je dois effectuer un traitement qui peut être assez lourd, par exemple un tri sur un tableau imposant. J'aimerais bien threader ca parce que ca freeze l'interface durant toute l'opération. De plus il faut que l'interface puisse être prévenue de l'avancement du tri, via une progressbar par exemple. Et bien évidemment il faut que je récupère les données triées à la fin du thread.

Est ce possible de faire cela à l'aide d'un thread javascript ? J'ai fait quelques tentatives infructueuse qui me freeze complètement FF...

# Re: Thread javascript

Envoyé par : Paul Rouget

Date : 15/08/2006 16:02

Comment t'y prends tu ?

# Re: Thread javascript

Envoyé par : David Marteau

Date : 15/08/2006 16:18

Les threads en JS sont un peu chatouilleux et il ya quelques rêgles à respecter pour que cela marche bien :

  1. Ne jamais accéder à un objet du DOM depuis le thread.
  2. Communiquer vers le thread principal en utilisant des proxy cf. http://www.xulfr.org/wiki/ThreadJavascri(..)

Le deuxième point implique que tes observeurs (pour l'état d'avancement de ton tri pas exemple) sont des objets qui ont une interface XPCOM.

# Re: Thread javascript

Envoyé par : papy

Date : 15/08/2006 17:00

Alors en gros j'ai essayé de faire comme ca :

Thread :

var myThread = {
    initData: null,

    filteredData: null,

    run: function() {
        var ObserverService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);

        var l = this.initData.length;
        for(var i = 0; i < l; i++) {
            if(this.initData[i].type == 'error')
                this.filteredData.push(this.initData[i]);

            ObserverService.notifyObservers(this, "progress", i * 100 / l);
        }

        ObserverService.notifyObservers(this, "end", null);
    }
};

UI :

var test = {
    filter: function(data) {
        var threadService = Components.classes["@mozilla.org/thread;1"].getService(Components.interfaces.nsIThread);
        var ObserverService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);

        ObserverService.addObserver(this, "progress" , false );
        ObserverService.addObserver(this, "end" , false );

        myThread.initData = data;
        threadService.init(myThread, 1024, 
                           Components.interfaces.nsIThread.PRIORITY_NORMAL,
                           Components.interfaces.nsIThread.SCOPE_GLOBAL,
                           Components.interfaces.nsIThread.STATE_UNJOINABLE);
    },

    observe: function(subject, topic, data) {
        if(topic == 'progess') {
            dump('avancement ' + data + '\n');
        } else if(topic == 'end')
            this.endProcess();
    },

    endProcess: function() {
        var ObserverService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);

        ObserverService.removeObserver(this, "progress");
        ObserverService.removeObserver(this, "end");

        var filtererdData = myThread.filteredData;

        var l = filteredData.length;
        for(var i = 0; i < l; i++)
            dump(filteredData[i].type + '\n');
    }
};

Ce code me fait violement planter FF, est apparement on ne peut pas utiliser la commande dump depuis un thread, ce qui est fort genant pour le debuggage (peut etre via un composant XPCOM ?)

Ca doit venir des mes observers qui n'ont pas d'interface XPCOM vu ce que disait David juste avant. Je commence à connaître quelques trucs en XUL maintenant, mais je dois avouer que la partie XPCOM reste bien floue pour moi et je me contente d'utiliser le code sans trop chercher plus loin.

En tout cas si j'arrive a faire marcher cet exemple je ferais un petit truc la dessus sur le Wiki, parce que la doc sur ce sujet est vraiment légère (je ne parle pas de xulfr en particulier ;))

# Re: Thread javascript

Envoyé par : David Marteau

Date : 15/08/2006 17:45

oui, effectivement tu peux oublier dump, et la plupart des fonctions qui font des entrées/sortie.

Ce ne sont pas tes observeurs qui sont en cause , car ceux-ci sont appelés via l'observer-service. Par contre l'observer-service n'est absolument pas thread-safe et tu dois récupérer un proxy dessus pour pouvoir l'utiliser dans ton thread ( cela ne posera pas de problèmes puisqu'il sagit d'un objet xpcom ).

# Re: Thread javascript

Envoyé par : papy

Date : 15/08/2006 22:54

Merci pour toutes ces indications, j'ai réussi à faire marcher mon thread et effectuer une notification via un ObserverService proxyfié, tout fonctionne nickel.

Juste un petit point noir, la gestion des erreurs. Les problèmes sont extrèmement dur à debugger. Au début j'ai pensé encapsuler le thread dans un objet de manière à pouvoir debugger plus facilement avec une structure qui ressemble à ca :

function Thread() {
    //ajout de l'objet comme observer du topic threadException
}

Thread.prototype = {

    function init() {
        //demarrage du thread en utilisant this en tant qu'objet runnable
    }

    function run() {
        //initialisation du proxy observerservice
        try {
            this.execute();
        } catch(e) {
            //notification de l'observeur avec topic threadException
        }
    }

    function execute();
        //fonction a surcharger pour le corps du thread
        ... 
    }

    function observe(subject, topic, data) {
        //si topic == threadException, dump de l'exception passé par data
    }
}

Mais j'ai l'impression que les erreurs font partir le thread dans le décor même avec le bloc try/catch. J'ai simplifié la structure pour éviter les problèmes, et en partant du code qui marche que j'ai mis en place, je rajoute tt dans un bloc try/catch, et je génère une petite exception avec le code suivant à la fin de mon traitement

var tmp = null;
tmp.value == 0;

Que le bloc catch contienne ou non des instructions ne change rien au problème, ca plante :(

En résumé tout fonctionne correctement, mais il faut faire un code parfait du premier coup ou tester la fonction hors du thread pendant le développement sous peine de se voir redémarrer FF toutes les 10 secondes sans informations sur le problème.

# Re: Thread javascript

Envoyé par : Paul Rouget

Date : 16/08/2006 19:30

... tout l'intéret d'avoir un Firefox compilé en mode debug :) Il dump sur la console des informations qui sont très utiles.

# Re: Thread javascript

Envoyé par : papy

Date : 17/08/2006 10:47

Effectivement mais je préfèrerais éviter, c'est assez long quand même... En ce qui concerne le try/catch, est-ce normal que ca ne fonctionne pas dans le contexte d'un thread, et si oui pourquoi.

# Re: Thread javascript

Envoyé par : Paul Rouget

Date : 17/08/2006 11:02

Hum... si, ça devrait. Après, que fais tu dans ton catch ? Parce que si tu fais un alert ou un dump, c'est normal que ça ne fonctionne pas.

# Re: Thread javascript

Envoyé par : papy

Date : 17/08/2006 11:05

Au début j'ai essayé de notifier mon observer via le proxy avec le topic 'threadException' histoire de le dumper depuis le thread principale, mais ca ne marchait pas. J'ai essayé de laisser le bloc catch vide pour ignorer complètement l'exception, même effet, firefox freeze.

# Re: Thread javascript

Envoyé par : zeyous

Date : 14/12/2006 23:56

Salut, je reprend ce thread car c'est exactement ce dont j'ai besoin, il m'a été utile jusqu'ici merci mais il y a quelque chose qui foire chez moi :

Je dois notifier la fin de mon thread, j'essaye avec ObserverService mais apparement je dois proxyfier cet objet avant la notification.

Comment faire cela, je crois qu'il faut utiliser getProxyForObject mais je n'ai aucune idée de quels paramètres mettre ?

Pour l'instant j'ai ça :

var myThread = {
   run: function() {

   var ObserverServiceClass = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
   var po = Components.classes["@mozilla.org/xpcomproxy;1"].getService(Components.interfaces.nsIProxyObjectManager);
   var proxiedObserver = po.getProxyForObject(?,Components.interfaces.nsIObserverService,ObserverServiceClass, PROXY_ALWAYS | PROXY_SYNC);

...traitement 

   proxiedObserver.notifyObservers(this, "end", null);
   }
};

Merci de votre aide ;)

Aller à la page :  1 2

Il n'est plus possible de poster des messages dans ce forum.


Copyright © 2003-2013 association xulfr, 2013-2016 Laurent Jouanneau - Informations légales.

Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™ sont des marques de la fondation Mozilla.